home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / word / filect.zip / FILECTRL.ASM next >
Assembly Source File  |  1993-03-10  |  115KB  |  3,324 lines

  1. COMMENT ~
  2.  
  3.    FILECTRL * Michael J. Mefford
  4.  
  5.    File viewer and deleter
  6.  
  7.    Fix 6-21-91 for WP Variable length multi-byte.
  8.    Fix 7-2-91 for NEXT_COUNT2: segment override.
  9.  
  10. ;--------------------------------------------------------------------;
  11. ~
  12.  
  13. _TEXT          SEGMENT PUBLIC 'CODE'
  14.                ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
  15.  
  16.                ORG     100H
  17. START:         JMP     MAIN
  18.  
  19. ;              DATA AREA
  20. ;              ---------
  21. COLOR_ATTRIBS  STRUC
  22. B              DB      71H                     ;Blue on lt. gray
  23. W              DB      17H                     ;Lt. gray on blue
  24. C              DB      31H                     ;Blue on cyan
  25. I              DB      1FH                     ;White on blue
  26. D              DB      17H                     ;Lt. gray on blue
  27. A              DB      07H                     ;White on black
  28. COLOR_ATTRIBS  ENDS
  29.  
  30. COLOR          COLOR_ATTRIBS  <>
  31.  
  32. COLOR_ATTR     COLOR_ATTRIBS  <>
  33. MONO_ATTR      COLOR_ATTRIBS  <70H, 07H, 70H, 0FH, 0FH, 70H>
  34.  
  35. BORDER_FLAG    DB      0                       ; =1 to disable.
  36.  
  37. ASCEND         EQU     0
  38. DESCEND        EQU     3
  39.  
  40. NAME_SORT      EQU     0                       ;Index into SORT_TABLE               JNZ
  41. EXT_SORT       EQU     4
  42. SIZE_SORT      EQU     8
  43. DATE_SORT      EQU     12
  44. NO_SORT        EQU     0FFH
  45.  
  46. SORT_ORDER     DW      ASCEND                  ;Index into SORTS_CODE (0 or 3)
  47. SORT_INDEX     DW      NAME_SORT               ;Default is Name.
  48.  
  49. COPYRIGHT      DB      "FILECTRL 1.1 Copyright (c) 1991 Michael J. Mefford",CR,LF
  50. FIRST_RIGHTS   DB      "First Published in PC Magazine, July 16, 1991",CR,LF,LF
  51.  
  52. SYNTAX LABEL BYTE
  53. DB  "Syntax: FILECTRL [filespec] [options]",CR,LF,LF
  54.  
  55. DB  "/M [+|-] + = Only include files modified since last backup",CR,LF
  56. DB  "         - = Only include files NOT modified since last backup",CR,LF
  57. DB  "/H = Include Hidden files",CR,LF
  58. DB  "/R = Include Read-only files",CR,LF
  59. DB  "/P date = Only include files ON or Prior date",CR,LF
  60. DB  "/A date = Only include files ON or After date",CR,LF
  61. DB  "   date format = mm/dd/yy",CR,LF
  62. DB  "/W WordStar files; remove high bit",CR,LF
  63. DB  "/N = Sort by Name",CR,LF
  64. DB  "/E = Sort by Extension",CR,LF
  65. DB  "/S = Sort by Size",CR,LF
  66. DB  "/D = Sort by Date",CR,LF
  67. DB  "/O = Sort by Original DOS DIR order",CR,LF
  68. DB  "     default = Sort by Name",CR,LF
  69. DB  "/F   Sort in descending order",CR,LF
  70. DB  "$"
  71.  
  72. SWITCH_CHARS    DB     "MHRP"
  73.                 DB     "AWNE"
  74.                 DB     "SDOF"
  75. SWITCH_LEN      EQU    $ - SWITCH_CHARS
  76.  
  77. SWITCH_DISPATCH DW     SW_MODIFIED, SW_HIDDEN,   SW_READ_ONLY, SW_PRIOR
  78.                 DW     SW_AFTER,    SW_WORDSTAR, SW_NAME,      SW_EXT
  79.                 DW     SW_SIZE,     SW_DATE,     SW_ORIGINAL,  SW_FORMAT
  80.  
  81.  
  82. TAB            EQU     9
  83. CR             EQU     13
  84. LF             EQU     10
  85. CTRL_Z         EQU     26
  86. SPACE          EQU     32
  87. BOX            EQU     254
  88. FF             EQU     12
  89. SHIFT_KEYS     EQU     3
  90. ESC_SCAN       EQU     1
  91. Y_SCAN         EQU     15H
  92. N_SCAN         EQU     31H
  93. F1_SCAN        EQU     3BH
  94. F2_SCAN        EQU     3CH
  95. F3_SCAN        EQU     3DH
  96. F4_SCAN        EQU     3EH
  97. F5_SCAN        EQU     3FH
  98. F6_SCAN        EQU     40H
  99. F7_SCAN        EQU     41H
  100. F8_SCAN        EQU     42H
  101. F9_SCAN        EQU     43H
  102. F10_SCAN       EQU     44H
  103. KB_FLAG        EQU     17H
  104. UP_SCAN        EQU     48H
  105. DOWN_SCAN      EQU     50H
  106. LEFT_SCAN      EQU     4BH
  107. RIGHT_SCAN     EQU     4DH
  108. PGUP_SCAN      EQU     49H
  109. PGDN_SCAN      EQU     51H
  110. BS_SCAN        EQU     0EH
  111. DEL_SCAN       EQU     53H
  112. HOME_SCAN      EQU     47H
  113. END_SCAN       EQU     4FH
  114. ENTER_SCAN     EQU     1CH
  115. TAB_SCAN       EQU     0FH
  116. CTRL_HOME_SCAN EQU     77H
  117. CTRL_END_SCAN  EQU     75H
  118. PLUS1_SCAN     EQU     0DH
  119. PLUS2_SCAN     EQU     4EH
  120. MINUS1_SCAN    EQU     0CH
  121. MINUS2_SCAN    EQU     4AH
  122. SHIFT_F4       EQU     57H
  123. SHIFT_F5       EQU     58H
  124. SHIFT_F6       EQU     59H
  125. SHIFT_F9       EQU     5CH
  126. SHIFT_F10      EQU     5DH
  127. CTRL_F2        EQU     5FH
  128. ALT_F1         EQU     68H
  129. SPACE_SCAN     EQU     39H
  130.  
  131. LEFT_ARROW     EQU     27
  132. RIGHT_ARROW    EQU     26
  133. UP_ARROW       EQU     24
  134. DOWN_ARROW     EQU     25
  135. COMMA          EQU     ","
  136. DECIMAL_POINT  EQU     "."
  137. PLUS_SIGN      EQU     "+"
  138. MINUS_SIGN     EQU     "-"
  139. NOTE           EQU     1046                    ; C
  140.  
  141. PORT_A         EQU     60H
  142.  
  143. TRUE           EQU     1
  144. FALSE          EQU     0
  145.  
  146. WORDSTAR_MASK  DB      0FFH                    ;Storage for WordStar mask.
  147. WORDSTAR       DB      0FFH                    ;7Fh if strip WordStar high bit.
  148. DOS_VERSION    DW      ?
  149. SCREEN_COLOR   DB      ?
  150. BREAK          DB      ?
  151. DEFAULT_DRIVE  DB      ?
  152. WORKING_DRIVE  DB      ?
  153. CURRENT_DIR    DB      66 DUP (?)
  154. WORKING_DIR    DB      66 DUP (?)
  155.  
  156. MATCHING       STRUC
  157. RESERVED       DB      21 DUP (?)
  158. ATTRIBUTE      DB              ?
  159. FILE_TIME      DW              ?
  160. FILE_DATE      DW              ?
  161. SIZE_LOW       DW              ?
  162. SIZE_HIGH      DW              ?
  163. FILE_NAME      DB      13 DUP (?)
  164. MATCHING       ENDS
  165.  
  166. FILE_RECORD    STRUC
  167. MARK           DB              ?
  168. LIST_NAME      DB      12 DUP (?)
  169. LIST_BYTES     DB       8 DUP (?)
  170. LIST_DATE      DB      11 DUP (?)
  171. LIST_TIME      DB       8 DUP (?)
  172. FILE_RECORD    ENDS
  173.  
  174. DIR_PTRS       STRUC
  175. TOP_LOC        DW      ?
  176. BAR_LOC        DW      ?
  177. DIR_PTRS       ENDS
  178.  
  179. DIR_LEVEL      DW      0
  180. DIR_LEVEL_MAX  EQU     20
  181. DIR_POINTERS   DIR_PTRS DIR_LEVEL_MAX DUP (<>)
  182.  
  183. KILOBYTES      =       1024
  184. PARAGRAPH      =       16
  185. FILENAME_SIZE  =       64                      ;64K
  186. FILEBUFF_SIZE  =       8                       ;8K
  187. FILENAME_SEG   DW      ?
  188. FILEBUFF_SEG   DW      ?
  189.  
  190. TEMP_RECORD    EQU     FILENAME_SIZE * KILOBYTES - SIZE FILE_RECORD
  191.  
  192. DTA            DB      SIZE MATCHING DUP (?)
  193. MARK_NAME      DB      ?                       ;Mark part of name.
  194. ASCIIZ_NAME    DB      13 DUP (?)              ;ASCIIZ name.
  195.  
  196. EOF_FLAG       DB      FALSE
  197. CURRENT_PAGE   DW      0
  198. BUFFER_PTR     DW      0
  199. BYTES_READ     DW      ?
  200. FILE_POINTER   DW      ?,?
  201. BUFFER_END     DW      ?
  202. FILE_END       DW      ?,?
  203. PAGE_INDEX     DW      0       ;Index to current page address.
  204. PAGE_MAX       EQU     256 * 2 ; 2 bytes per page
  205. PAGES          DW      PAGE_MAX DUP (?)
  206. FAIL_FLAG      DB      FALSE                   ;True if open failed.
  207. FILE_TYPE      DW      ?     ;Address of file-type handler.
  208. FILE_LINE      DW      ?     ;Address of file-lines handler.
  209. ROW            DW      0
  210. EXEC_EXTENSION DB      "EXECOM"
  211.  
  212.  
  213. CRT_MODE       EQU     49H
  214. CRT_COLS       EQU     4AH
  215. CRT_ROWS       EQU     84H
  216. COLUMNS        DW      ?
  217. CRT_WIDTH      DW      ?
  218. CRT_START      DW      ?
  219. STATUS_REG     DW      3BAH
  220. VIDEO_SEG      DW      0B000H
  221. ROWS           DB      24
  222.  
  223. LISTING_LEN    DW      ?
  224. LISTING_ADDR   DW      0
  225. BAR_ADDR       DW      0
  226. LAST_ADDR      DW      ?
  227.  
  228. FILENAME       DW      ?                       ;Address of filespec to parse.
  229. FILESPEC       DW      ?                       ;Address of parsed filespec.
  230. FILESPEC_END   DW      ?
  231. ATTR           DW      10H                     ;Default = normal files and DIRs.
  232.  
  233. CASE           DB      5FH    ;Capitalize; =FFh if case sensitive.
  234. JB_CODE        EQU     72H
  235. JA_CODE        EQU     77H
  236.  
  237. STATE          DW      LISTING
  238. FILE_CURRENT   DB      FALSE
  239.  
  240. SHORT_NAME     EQU     0
  241. LONG_NAME      EQU     1
  242. FULL_FILE      EQU     2
  243. ZOOM_STATE     DB      SHORT_NAME
  244.  
  245. LCOLUMN_START  DW      ?
  246. LCOLUMN_LEN    DW      ?
  247. LCOLUMN_BAL    DW      ?
  248.  
  249. FCOLUMN_START  DW      ?
  250. FCOLUMN_LEN    DW      ?
  251.  
  252. MENU           LABEL   BYTE
  253. DB " F2 Remove  F3 New  F5 Zoom   F6 Sort "
  254. SORT_MENU1     DB      ?
  255. DB                                       " ("
  256. SORT_MENU2     DB      ?
  257. DB                                         ")  F7 Name  F8 Ext  F9 Size  F10 Date",0
  258. DB " Ctrl-F2 Remove marked   +/- Mark/Unmark   "
  259. DB "Tab, ", LEFT_ARROW, SPACE, RIGHT_ARROW, " select window   Esc to Exit",0
  260.  
  261. PARENT         DB      "Dot-dot is the Parent directory",0
  262. STAR_DOT_STAR  DB      "*.*",0
  263. NOT_ENOUGH     DB      "Not enough memory",CR,LF,LF,"$"
  264. NOT_FOUND      DB      "File not found",CR,LF,LF,"$"
  265. ILLEGAL_PARAM  DB      "Illegal parameter"
  266. CRLFLF         DB       CR,LF,LF,"$"
  267.  
  268. ;              CODE AREA
  269. ;              ---------
  270. KBD_STATUS     DB      ?
  271.  
  272. INT_9          PROC    NEAR
  273.  
  274.                PUSH    AX
  275.                IN      AL,PORT_A
  276.                CMP     AL,0E0H
  277.                JZ      INT_9_END
  278.                CMP     AL,0E1H
  279.                JZ      INT_9_END
  280.                MOV     CS:KBD_STATUS,AL
  281.  
  282. INT_9_END:     POP     AX
  283.                JMP     DWORD PTR CS:OLD9
  284.  
  285. INT_9          ENDP
  286.  
  287. ;----------------------------------------------;
  288. INT_24         PROC    NEAR
  289.  
  290.                STI
  291.                PUSHF
  292.                MOV     CS:FAIL_FLAG,TRUE
  293.                MOV     AL,3
  294.                CMP     CS:DOS_VERSION,300H
  295.                JAE     INT_24_END
  296.                XOR     AL,AL
  297. INT_24_END:    POPF
  298.                IRET
  299.  
  300. INT_24         ENDP
  301.  
  302. ;----------------------------------------------;
  303.  
  304. MAIN           PROC    NEAR
  305.                CLD
  306.  
  307.                MOV     AH,30H
  308.                INT     21H
  309.                XCHG    AL,AH
  310.                MOV     DOS_VERSION,AX
  311.  
  312.                CALL    INSTALL_9
  313.                CALL    INSTALL_24
  314.  
  315.                XOR     BH,BH
  316.                MOV     AH,8
  317.                INT     10H
  318.                MOV     SCREEN_COLOR,AH
  319.  
  320.                MOV     AX,3300H                ;Get Ctrl-Break state.
  321.                INT     21H
  322.                MOV     BREAK,DL
  323.  
  324.                XOR     DL,DL
  325.                MOV     AX,3301H
  326.                INT     21H
  327.  
  328.                MOV     AH,19H                  ;Get default drive so can
  329.                INT     21H                     ; restore after we change it.
  330.                MOV     DEFAULT_DRIVE,AL
  331.                MOV     WORKING_DRIVE,AL
  332.  
  333.                MOV     SI,OFFSET CURRENT_DIR
  334.                CALL    GET_DIR
  335.  
  336.                MOV     BX,OFFSET STACK_POINTER + 15
  337.                MOV     CL,4
  338.                SHR     BX,CL
  339.                ADD     BX,(FILENAME_SIZE+FILEBUFF_SIZE) * (KILOBYTES/PARAGRAPH)
  340.                MOV     AH,4AH                  ;Allocate memory.
  341.                INT     21H
  342.                JNC     SETUP_STACK
  343.                MOV     DX,OFFSET NOT_ENOUGH
  344.                JMP     SHORT ERROR_EXIT          ;If not enough, exit.
  345.  
  346. SETUP_STACK:   MOV     AX,OFFSET STACK_POINTER
  347.                MOV     SP,AX                   ;Set up stack.
  348.                ADD     AX,15
  349.                MOV     CL,4
  350.                SHR     AX,CL
  351.                MOV     CX,DS
  352.                ADD     AX,CX
  353.                MOV     FILENAME_SEG,AX         ;And data segments.
  354.                ADD     AX,FILENAME_SIZE * (KILOBYTES / PARAGRAPH)
  355.                MOV     FILEBUFF_SEG,AX
  356.  
  357.                MOV     DX,OFFSET DTA
  358.                MOV     AH,1AH
  359.                INT     21H
  360.  
  361.                MOV     FILENAME,81H
  362.                CALL    NEW_FILESPEC
  363.                JC      ERROR_EXIT
  364.                CALL    VIDEO_SETUP
  365.                CALL    DISP_DIR
  366.                CALL    INIT_ZOOM
  367.                CALL    DISPLAY_MENU
  368.                CALL    DISP_LISTING
  369.                CALL    DISP_FILE
  370.                JMP     SHORT NEXT_KEY
  371.  
  372. ;************* Main Loop *************;
  373.  
  374. NEXT_KEY:      CALL    GETKEY
  375.                JC      GOOD_EXIT
  376.                CMP     AH,CR
  377.                JNZ     CK_PLUS
  378.                CALL    ENTER
  379.                JMP     NEXT_KEY
  380.  
  381. CK_PLUS:       CMP     AH,"+"
  382.                JZ      MAIN_DISPATCH
  383.                CMP     AH,"-"
  384.                JZ      MAIN_DISPATCH
  385.                CMP     AH,SPACE
  386.                JBE     MAIN_DISPATCH
  387.                CALL    SEARCH
  388.                JMP     NEXT_KEY
  389.  
  390. MAIN_DISPATCH: CALL    [STATE]
  391.                JMP     NEXT_KEY
  392.  
  393. ;----------------------------------------------;
  394.  
  395. ERROR_EXIT:    CALL    PRINT_STRING
  396.                MOV     AL,1
  397.                JMP     SHORT EXIT
  398.  
  399. GOOD_EXIT:     CALL    CLOSE_SCREEN
  400.                XOR     AL,AL                   ;EL=0.
  401.  
  402. EXIT:          PUSH    AX
  403.                CALL    UNINSTALL_9
  404.                CALL    RESTORE_DIR
  405.                MOV     DL,DEFAULT_DRIVE
  406.                MOV     AH,0EH
  407.                INT     21H
  408.  
  409.                MOV     DL,BREAK
  410.                MOV     AX,3301H
  411.                INT     21H
  412.  
  413. TERMINATE:     MOV     DX,OFFSET COPYRIGHT
  414.                CALL    PRINT_STRING
  415.                POP     AX
  416.                MOV     AH,4CH
  417.                INT     21H
  418.  
  419. MAIN           ENDP
  420.  
  421.  
  422. ;**************
  423. ; SUBROUTINES *
  424. ;**************
  425. SEARCH:        PUSH    DS
  426.  
  427.                CMP     STATE,OFFSET LISTING
  428.                JNZ     NO_MATCH
  429.  
  430.                CMP     AH,"a"
  431.                JB      DO_SEARCH
  432.                CMP     AH,"z"
  433.                JA      DO_SEARCH
  434.                AND     AH,5FH
  435.  
  436. DO_SEARCH:     MOV     SI,BAR_ADDR
  437.                MOV     DS,FILENAME_SEG
  438.                CMP     [SI.LIST_NAME],AH
  439.                JZ      NEXT_SEARCH
  440.                XOR     SI,SI
  441.                JMP     SHORT NEXT_SEARCH2
  442.  
  443. NEXT_SEARCH:   ADD     SI,SIZE FILE_RECORD
  444. NEXT_SEARCH2:  CMP     [SI.LIST_NAME],-1
  445.                JZ      NO_MATCH
  446.                CMP     [SI.LIST_NAME],AH
  447.                JNZ     NEXT_SEARCH
  448.  
  449.                POP     DS
  450.                MOV     BAR_ADDR,SI
  451.                MOV     AX,LISTING_LEN
  452.                SHR     AX,1
  453.                MOV     BX,SIZE FILE_RECORD
  454.                MUL     BX
  455.                SUB     SI,AX
  456.                JNC     STORE_MATCH
  457.                XOR     SI,SI
  458. STORE_MATCH:   MOV     LISTING_ADDR,SI
  459.                MOV     FILE_CURRENT,FALSE
  460.                JMP     SHORT SEARCH_END
  461.  
  462. NO_MATCH:      POP     DS
  463.                CALL    BEEP
  464.  
  465. SEARCH_END:    CALL    DISP_LISTING
  466.                CALL    DISP_FILE
  467.                RET
  468.  
  469. ;----------------------------------------------;
  470.  
  471. M_TAB:         JMP     SHORT DO_TOGGLE
  472.  
  473. M_LEFT:        CMP     STATE,OFFSET LISTING
  474.                JZ      TOGGLE_END
  475.                JMP     SHORT DO_TOGGLE
  476.  
  477. M_RIGHT:       CMP     STATE,OFFSET FILE
  478.                JZ      TOGGLE_END
  479.  
  480. DO_TOGGLE:     MOV     BX,OFFSET FILE
  481.                CMP     STATE,OFFSET FILE
  482.                JNZ     CHANGE_STATE
  483.                MOV     BX,OFFSET LISTING
  484.                CMP     ZOOM_STATE,FULL_FILE
  485.                JNZ     CHANGE_STATE
  486.                MOV     AL,LAST_ZOOM
  487.                MOV     ZOOM_STATE,AL
  488. CHANGE_STATE:  MOV     STATE,BX
  489.                CALL    INIT_ZOOM
  490.                CALL    DISP_LISTING
  491.                CALL    DISP_FILE
  492.  
  493. TOGGLE_END:    RET
  494.  
  495. ;----------------------------------------------;
  496.  
  497. L_DISPATCH     DB      UP_SCAN,      DOWN_SCAN,   PGUP_SCAN,    PGDN_SCAN
  498.                DB      HOME_SCAN,    END_SCAN,    PLUS1_SCAN,   PLUS2_SCAN
  499.                DB      MINUS1_SCAN,  MINUS2_SCAN, SPACE_SCAN
  500.  
  501.                DB      TAB_SCAN,     LEFT_SCAN,   RIGHT_SCAN,   SHIFT_F5
  502.                DB      F2_SCAN,      F3_SCAN,     F5_SCAN,      F6_SCAN
  503.                DB      F7_SCAN,      F8_SCAN,     F9_SCAN,      F10_SCAN
  504.                DB      CTRL_F2
  505.  
  506. L_LEN          EQU     $ - L_DISPATCH
  507.  
  508.                DW      LUP,          LDOWN,       LPGUP,        LPGDN
  509.                DW      LHOME,        LEND,        PLUS,         PLUS
  510.                DW      MINUS,        MINUS,       FLOP_MARK
  511.  
  512.                DW      M_TAB,        M_LEFT,      M_RIGHT,      SHIFT_ZOOM
  513.                DW      REMOVE,       NEW_FILE,    ZOOM,         SORT_DIR
  514.                DW      SORT_NAME,    SORT_EXT,    SORT_SIZE,    SORT_DATE
  515.                DW      REMOVE_MARKS
  516.  
  517. ;INPUT: AL=scan code.
  518.  
  519. LISTING:       MOV     DI,OFFSET L_DISPATCH
  520.                MOV     CX,L_LEN
  521.                CALL    DISPATCH
  522.                CALL    DISP_LISTING
  523.                RET
  524.  
  525. ;----------------------------------------------;
  526. ; INPUT: AX=Listing page; BP=BAR_ADDR; DX=LISTING_ADDR; CX=LAST_ADDR.
  527. ; OUTPUT: LISTING_FLAG=TRUE if listing changed.
  528.  
  529. FLOP_MARK:     PUSH    DS
  530.                MOV     DS,FILENAME_SEG
  531.                MOV     AL,DS:[BP]
  532.                CMP     AL,"<"
  533.                JNZ     GET_FLOP
  534.                POP     DS
  535.                JMP     LPAGE_END
  536. GET_FLOP:      MOV     AH,SPACE
  537.                CMP     AL,AH
  538.                JNZ     DO_FLOP
  539.                MOV     AH,RIGHT_ARROW
  540. DO_FLOP:       MOV     DS:[BP],AH
  541.                POP     DS
  542.                JMP     LPAGE_END
  543.  
  544.  
  545. PLUS:          MOV     AL,RIGHT_ARROW         ;Use little right arrow for mark.
  546.                JMP     SHORT PLUSMINUS
  547.  
  548. MINUS:         MOV     AL,SPACE                ;Remove mark with space char.
  549.  
  550. PLUSMINUS:     PUSH    DS
  551.                MOV     DS,FILENAME_SEG
  552.                CMP     DS:BYTE PTR [BP],"<"
  553.                JZ      PLUSMINUS2
  554.                MOV     DS:[BP],AL
  555. PLUSMINUS2:    POP     DS
  556.                JMP     SHORT LDOWN
  557.  
  558.  
  559. LUP:           SUB     BP,SIZE FILE_RECORD     ;Move bar up a line.
  560.                JL      LPAGE_END               ;If < 0, ignore.
  561.                CMP     BP,DX                   ;If bar below top, OK.
  562.                JAE     LPAGE_UPDATE
  563.                SUB     DX,SIZE FILE_RECORD     ;Else, move listing up a line.
  564.                JMP     SHORT LPAGE_UPDATE
  565.  
  566. LDOWN:         ADD     BP,SIZE FILE_RECORD     ;Move bar down a line.
  567.                CMP     BP,CX                   ;If > last line, then ignore.
  568.                JA      LPAGE_END
  569.                ADD     AX,DX                   ;Listing top + page length =
  570.                CMP     BP,AX                   ; listing bottom; If bar below
  571.                JB      LPAGE_UPDATE            ; listing bottom, OK.
  572.                ADD     DX,SIZE FILE_RECORD     ;Else move listing down a line.
  573.                JMP     SHORT LPAGE_UPDATE
  574.  
  575. LPGUP:         SUB     BP,AX                   ;Move bar up a page.
  576.                SUB     DX,AX                   ;Move listing up a page.
  577.                JC      LHOME                   ;If listing < top, then home.
  578.                JMP     SHORT LPAGE_UPDATE      ;Else, OK.
  579.  
  580. LPGDN:         ADD     DX,AX                   ;Move listing down a page.
  581.                CMP     DX,CX                   ;If <= last line, do bar.
  582.                JBE     DO_BAR
  583.                SUB     DX,AX                   ;Else, back to where we were
  584.                MOV     BP,CX                   ; and move bar to last line
  585.                JMP     SHORT LPAGE_UPDATE      ; and update.
  586. DO_BAR:        ADD     BP,AX                   ;Move bar down a page.
  587.                CMP     BP,CX                   ;If bar <= last line, OK.
  588.                JBE     LPAGE_UPDATE
  589.                MOV     BP,CX                   ;Else, move bar to last line.
  590.                JMP     SHORT LPAGE_UPDATE
  591.  
  592. LHOME:         XOR     BP,BP                   ;Move bar to top.
  593.                XOR     DX,DX                   ;Move listing to top.
  594.                JMP     SHORT LPAGE_UPDATE
  595.  
  596. LEND:          MOV     BP,CX                   ;Move bar to last line.
  597.                ADD     CX,SIZE FILE_RECORD     ;Last line + 1 - page length =
  598.                SUB     CX,AX                   ; top of last page.
  599.                CMP     DX,CX                   ;If less than a full page,
  600.                JG      LPAGE_UPDATE            ; then already at last page.
  601.                MOV     DX,CX                   ;Else, move listing to last page.
  602.  
  603. LPAGE_UPDATE:  MOV     BAR_ADDR,BP             ;Store the new bar
  604.                MOV     LISTING_ADDR,DX         ; and listing line start.
  605.                MOV     FILE_CURRENT,FALSE
  606.                MOV     FAIL_FLAG,FALSE
  607.  
  608. LPAGE_END:     RET
  609.  
  610. ;----------------------------------------------;
  611. F_DISPATCH     DB      UP_SCAN,      DOWN_SCAN,   PGUP_SCAN,    PGDN_SCAN
  612.                DB      HOME_SCAN,    END_SCAN
  613.  
  614.                DB      TAB_SCAN,     LEFT_SCAN,   RIGHT_SCAN,   SHIFT_F5
  615.                DB      F2_SCAN,      F3_SCAN,     F5_SCAN,      F6_SCAN
  616.                DB      F7_SCAN,      F8_SCAN,     F9_SCAN,      F10_SCAN
  617.                DB      CTRL_F2
  618.  
  619. F_LEN          EQU     $ - F_DISPATCH
  620.  
  621.                DW      FUP,          FDOWN,       FPGUP,        FPGDN
  622.                DW      FHOME,        FEND
  623.  
  624.                DW      M_TAB,        M_LEFT,      M_RIGHT,      SHIFT_ZOOM
  625.                DW      REMOVE,       NEW_FILE,    ZOOM,         SORT_DIR
  626.                DW      SORT_NAME,    SORT_EXT,    SORT_SIZE,    SORT_DATE
  627.                DW      REMOVE_MARKS
  628.  
  629. FILE:          CMP     FILE_CURRENT,TRUE
  630.                JZ      DISPATCH_FILE
  631.                CALL    OPEN_FILE
  632.                JC      END_FILE
  633.  
  634. DISPATCH_FILE: MOV     DI,OFFSET F_DISPATCH
  635.                MOV     CX,F_LEN
  636.                CALL    DISPATCH
  637. END_FILE:      RET
  638.  
  639. ;----------------------------------------------;
  640. FUP:           CMP     ROW,0
  641.                JNZ     DEC_ROW
  642.                CMP     PAGE_INDEX,0
  643.                JNZ     CK_UP
  644.                JMP     NO_UPDATE
  645. CK_UP:         MOV     AX,LISTING_LEN
  646.                DEC     AX
  647.                MOV     ROW,AX
  648.                JMP     SHORT FPGUP
  649. DEC_ROW:       DEC     ROW
  650.                JMP     FILE_UPDATE
  651.  
  652. ;--------------;
  653. FDOWN:         MOV     AX,ROW
  654.                INC     AX
  655.                MOV     ROW_CNT,AX
  656.                MOV     SI,CURRENT_PAGE
  657.                MOV     BYTE PTR DISPLAY_FLAG,FALSE
  658.                PUSH    DS
  659.                MOV     DS,FILEBUFF_SEG
  660. FDOWN2:        CALL    CS:[FILE_LINE]
  661.                DEC     CS:ROW_CNT
  662.                JNZ     FDOWN2
  663.                POP     DS
  664.                CMP     SI,BUFFER_END
  665.                JNZ     CK_ROW
  666.                CMP     EOF_FLAG,TRUE
  667.                JZ      NO_UPDATE
  668.  
  669. CK_ROW:        MOV     AX,ROW
  670.                INC     AX
  671.                CMP     AX,LISTING_LEN
  672.                JB      INC_ROW
  673.                MOV     ROW,0
  674.                CALL    INC_PAGE
  675.                JMP     SHORT FILE_UPDATE
  676.  
  677. INC_ROW:       INC     ROW
  678.                JMP     SHORT FILE_UPDATE
  679.  
  680. ;--------------;
  681. FPGUP:         CMP     PAGE_INDEX,0
  682.                JNZ     DEC_PG
  683.                MOV     ROW,0
  684.                JMP     SHORT FILE_UPDATE
  685.  
  686. DEC_PG:        MOV     SI,CURRENT_PAGE
  687.                MOV     BX,PAGE_INDEX
  688.                SUB     SI,PAGES[BX]
  689.                JNC     DEC_PG2
  690.                CALL    BACKWARD
  691.                JMP     DEC_PG
  692. DEC_PG2:       SUB     PAGE_INDEX,2
  693.                MOV     CURRENT_PAGE,SI
  694.                JMP     SHORT FILE_UPDATE
  695.  
  696. ;--------------;
  697. FPGDN:         CALL    CK_PAGE
  698.                JC      NO_UPDATE
  699.                JMP     SHORT FILE_UPDATE
  700.  
  701. ;--------------;
  702. FHOME:         CALL    OPEN_FILE
  703.                JMP     SHORT FILE_UPDATE
  704.  
  705. ;--------------;
  706. FEND:          CALL    CK_PAGE
  707.                JNC     FEND
  708.  
  709. FILE_UPDATE:   CALL    DISP_FILE
  710. NO_UPDATE:     RET
  711.  
  712. ;--------------;
  713. CK_PAGE:       CMP     PAGE_INDEX,PAGE_MAX
  714.                JAE     NO_PAGE
  715.  
  716.                MOV     SI,CURRENT_PAGE
  717.                MOV     AX,LISTING_LEN
  718.                MOV     ROW_CNT,AX
  719.                MOV     BYTE PTR DISPLAY_FLAG,FALSE
  720.                PUSH    DS
  721.                MOV     DS,FILEBUFF_SEG
  722. NEXT_PAGE:     CALL    CS:[FILE_LINE]
  723.                DEC     CS:ROW_CNT
  724.                JNZ     NEXT_PAGE
  725.                POP     DS
  726.  
  727.                CMP     SI,BUFFER_END
  728.                JNZ     INC_PAGE
  729.                CMP     EOF_FLAG,TRUE
  730.                JZ      NO_PAGE
  731. INC_PAGE:      MOV     DX,CURRENT_PAGE
  732.                MOV     CURRENT_PAGE,SI
  733.                SUB     SI,DX
  734.                MOV     BX,PAGE_INDEX
  735.                INC     BX
  736.                INC     BX
  737.                MOV     PAGE_INDEX,BX
  738.                MOV     PAGES[BX],SI
  739.                CLC
  740.                JMP     SHORT CK_PAGE_END
  741.  
  742. NO_PAGE:       STC
  743. CK_PAGE_END:   RET
  744.  
  745. ;----------------------------------------------;
  746. ; OUTPUT: CF = 1 if failed.
  747.  
  748. OPEN_FILE:     PUSH    AX
  749.                MOV     BP,BAR_ADDR
  750.                CALL    MAKE_FILENAME
  751.                CMP     MARK_NAME,-1
  752.                JZ      OPEN_FAIL
  753.                CMP     MARK_NAME,"<"
  754.                JNZ     OPEN_FILE2
  755.                MOV     FILE_TYPE,OFFSET SUBDIR
  756.                MOV     FILE_LINE,OFFSET DUMMY_RET
  757.                JMP     SHORT OPEN_GOOD
  758.  
  759. OPEN_FILE2:    MOV     FILE_POINTER[0],0
  760.                MOV     FILE_POINTER[2],0
  761.                MOV     FILE_END[0],-1
  762.                MOV     FILE_END[2],-1          ;Large number to fill buffer.
  763.  
  764.                MOV     CURRENT_PAGE,FILEBUFF_SIZE * KILOBYTES / 2
  765.                MOV     PAGE_INDEX,0
  766.                MOV     ROW,0
  767.  
  768.                XOR     SI,SI
  769.                CALL    READ
  770.                JC      OPEN_FAIL
  771.                CALL    GET_TYPE
  772. OPEN_GOOD:     MOV     FILE_CURRENT,TRUE
  773.                CLC
  774.                JMP     SHORT OPEN_END
  775.  
  776. OPEN_FAIL:     CALL    CLEAR_FILE
  777.                CALL    BEEP
  778.                STC
  779.  
  780. OPEN_END:      POP     AX
  781.                RET
  782.  
  783. ;----------------------------------------------;
  784. ; INPUT:  SI -> Read offset (0 or FILEBUFF_SIZE * KILOBYTES / 2)
  785. ; OUTPUT: CF=1 if read failed.
  786.  
  787. READ:          CMP     FAIL_FLAG,TRUE
  788.                JNZ     READ_NAME
  789.                STC
  790.                JMP     READ_END
  791.  
  792. READ_NAME:     MOV     DX,OFFSET ASCIIZ_NAME
  793.                MOV     AX,3D00H
  794.                INT     21H
  795.                JC      READ_END
  796.                CMP     FAIL_FLAG,TRUE
  797.                STC
  798.                JZ      READ_END
  799.  
  800.                MOV     BX,AX
  801.  
  802.                MOV     DX,FILE_POINTER[0]
  803.                MOV     CX,FILE_POINTER[2]
  804.                MOV     AX,4200H
  805.                INT     21H
  806.                JC      CLOSE
  807.  
  808.                MOV     CX,DX
  809.                MOV     DX,AX
  810.                MOV     AX,FILE_END[0]
  811.                MOV     DI,FILE_END[2]
  812.                SUB     AX,DX
  813.                SBB     DI,CX
  814.                OR      AX,AX
  815.                JNZ     READ1
  816.                OR      DI,DI
  817.                JZ      DO_EOF
  818.  
  819. READ1:         MOV     CX,FILEBUFF_SIZE * KILOBYTES / 2
  820.                OR      DI,DI
  821.                JNZ     READ2
  822.                CMP     CX,AX
  823.                JB      READ2
  824.                MOV     CX,AX
  825.  
  826. READ2:         MOV     DX,SI
  827.                PUSH    DS
  828.                MOV     DS,FILEBUFF_SEG
  829.                MOV     AH,3FH
  830.                INT     21H
  831.                POP     DS
  832.                CMP     FAIL_FLAG,TRUE
  833.                STC
  834.                JZ      CLOSE
  835.  
  836.                MOV     BYTES_READ,AX
  837.                ADD     FILE_POINTER[0],AX
  838.                ADC     FILE_POINTER[2],0
  839.                MOV     DX,AX
  840.                ADD     DX,FILEBUFF_SIZE * KILOBYTES / 2
  841.                MOV     BUFFER_END,DX
  842.                MOV     EOF_FLAG,FALSE
  843.                CMP     AX,FILEBUFF_SIZE * KILOBYTES / 2
  844.                JZ      CLOSE1
  845.  
  846. DO_EOF:        MOV     EOF_FLAG,TRUE
  847.  
  848. CLOSE1:        CLC
  849.  
  850. CLOSE:         PUSHF
  851.                MOV     AH,3EH
  852.                INT     21H
  853.                POPF
  854.  
  855. READ_END:      RET
  856.  
  857. ;----------------------------------------------;
  858. FORWARD:       PUSH    AX
  859.                PUSH    BX
  860.                PUSH    CX
  861.                PUSH    DX
  862.                PUSH    DI
  863.                PUSH    BP
  864.                PUSH    DS
  865.                PUSH    ES
  866.  
  867.                MOV     CX,FILEBUFF_SIZE * KILOBYTES / 2
  868.                SUB     CS:BUFFER_PTR,CX
  869.                SUB     CS:CURRENT_PAGE,CX
  870.                MOV     SI,CX
  871.                XOR     DI,DI
  872.                MOV     AX,DS
  873.                MOV     ES,AX
  874.                SHR     CX,1
  875.                REP     MOVSW
  876.                MOV     SI,DI
  877.                PUSH    CS
  878.                POP     DS
  879.                CALL    READ
  880.  
  881.                POP     ES
  882.                POP     DS
  883.                POP     BP
  884.                POP     DI
  885.                POP     DX
  886.                POP     CX
  887.                POP     BX
  888.                POP     AX
  889. FORWARD_END:   RET
  890.  
  891. ;----------------------------------------------;
  892.  
  893. BACKWARD:      PUSH    DS
  894.                PUSH    ES
  895.                MOV     CX,FILEBUFF_SIZE * KILOBYTES / 2
  896.                ADD     CURRENT_PAGE,CX
  897.                MOV     DI,CX
  898.                XOR     SI,SI
  899.                MOV     AX,FILEBUFF_SEG
  900.                MOV     DS,AX
  901.                MOV     ES,AX
  902.                SHR     CX,1
  903.                REP     MOVSW
  904.                POP     ES
  905.                POP     DS
  906.  
  907.                MOV     AX,BYTES_READ
  908.                ADD     AX,FILEBUFF_SIZE * KILOBYTES
  909.                SUB     FILE_POINTER[0],AX
  910.                SBB     FILE_POINTER[2],0
  911.                XOR     SI,SI
  912.                CALL    READ
  913.                JC      BACKWARD_END
  914.                ADD     FILE_POINTER[0],FILEBUFF_SIZE * KILOBYTES / 2
  915.                ADC     FILE_POINTER[2],0
  916.  
  917. BACKWARD_END:  RET
  918.  
  919. ;----------------------------------------------;
  920. WP_FILE_PREFACE STRUC
  921. WPCorp_FILE_ID DB      -1,"WPC"                ;Signature
  922. START_OF_DOC   DW      ?,?
  923. PRODUCT_TYPE   DB      1                       ;WordPerfect
  924. WP_FILE_TYPE   DB      10                      ;Document
  925. MAJOR_VER      DB      0
  926. MINOR_VER      DB      0
  927. ENCRYPTION_KEY DW      0                       ;0 = not encrypted
  928. WP_RESERVED    DW      0
  929. WP_FILE_PREFACE ENDS
  930.  
  931. WP_PREFACE     WP_FILE_PREFACE <>
  932.  
  933. ;--------------;
  934. WORD_FILE_INFORMATION_BLOCK   STRUC
  935. wIdent         DW      0BE31H                  ;Signature
  936. dtyDW          DW      0                       ;Document type
  937. wTool          DW      0AB00H                  ;Signature
  938. pnNextFib      DW      ?                       ;Pointer to incremental save
  939. pnChar         DW      ?                       ;Pointer to Char formatting
  940. pnPlcpcd       DW      ?                       ;Pointer to piece table
  941. wReserved2     DW      ?                       ;Paragraph height table
  942. fcMac          DW      ?,?                     ;File char pos of file end
  943. pnPara         DW      ?                       ;Location of para formatting
  944. pnFntb         DW      ?                       ;Location of footnote table
  945. pnBkmk         DW      ?                       ;Bookmarks and sequence info
  946. pnSetb         DW      ?                       ;Section table
  947. pnBftb         DW      ?                       ;Buffer table
  948. pnSumd         DW      ?                       ;Summary information
  949. szSsht         DB      66 DUP(?)               ;Style sheet path
  950. wReserve       DW      ?                       ;For Windows Write use
  951. rgchPrtNm      DB      8  DUP(?)               ;Printer name
  952. pnMac          DW      ?                       ;One past end of document
  953. DOP            DB      8  DUP(?)               ;Document properties
  954. version        DB      ?                       ;word version
  955. fAsv           DB      ?                       ;Autosave
  956. pnPagb         DW      ?                       ;Word 5.0 page table
  957. pnMacBkmk      DW      ?                       ;Mac of Bkmk stuff
  958. pnFilename     DW      ?                       ;Only used for Asv files
  959. pnRhtb         DW      ?                       ;Running head table
  960. codepage       DW      ?                       ;codepage
  961. WORD_FILE_INFORMATION_BLOCK   ENDS
  962.  
  963. WORD_FIB       WORD_FILE_INFORMATION_BLOCK <>
  964.  
  965. ;--------------;
  966. QandA_HDR      STRUC
  967. sig            DB      "TBWP",0                ;Touchbase signature
  968. QandA_date     DB      13 DUP (?)              ;Date file last updated
  969. QandA_time     DB       9 DUP (?)              ;Time file last updated
  970. reltxtloc      DW      ?,?                     ;File rel loc of start of text
  971. txtsize        DW      ?,?                     ;Size of the text
  972. ver            DW      ?                       ;Version number
  973. ehdr           DB      ?                       ;End of file header
  974. QandA_HDR      ENDS
  975.  
  976. ;Q&A files have for the signature either
  977. ;    TBWP (TouchBase Word Processing file) or
  978. ;    TBTX (TouchBase TeXt file).
  979.  
  980. sig2           DB      "TBTX",0
  981.  
  982. QandA_HEADER   QandA_HDR <>
  983.  
  984. ;----------------------------------------------;
  985. GET_TYPE:      PUSH    DS
  986.                MOV     FILE_POINTER[0],0
  987.                MOV     FILE_POINTER[2],0
  988.  
  989. ;----------------;
  990. ; Executable
  991.                MOV     FILE_TYPE,OFFSET EXECUTABLE
  992.                MOV     FILE_LINE,OFFSET DUMMY_RET
  993.                MOV     BX,BAR_ADDR
  994.                ADD     BX,10                   ;Extension.
  995.                MOV     SI,BX
  996.                MOV     DS,FILENAME_SEG
  997.                MOV     DI,OFFSET EXEC_EXTENSION
  998.                MOV     CX,3
  999.                REPZ    CMPSB
  1000.                JZ      EXEC_TYPE
  1001.                MOV     SI,BX
  1002.                MOV     DI,OFFSET EXEC_EXTENSION + 3
  1003.                MOV     CX,3
  1004.                REPZ    CMPSB
  1005.                JNZ     GET_TYPE2
  1006. EXEC_TYPE:     POP     DS
  1007.                JMP     TYPE_END
  1008.  
  1009. ;----------------;
  1010. ;WordPerfect
  1011.  
  1012. GET_TYPE2:     MOV     DS,CS:FILEBUFF_SEG
  1013.                MOV     CS:FILE_TYPE,OFFSET DOCUMENT
  1014.                MOV     CS:FILE_LINE,OFFSET WP_LINES
  1015.                CMP     CS:BYTES_READ,SIZE WP_PREFACE
  1016.                JB      GET_TYPE3
  1017.                XOR     SI,SI
  1018.                MOV     DI,OFFSET WP_PREFACE
  1019.                MOV     CX,4
  1020.                REPZ    CMPSB
  1021.                JNZ     GET_TYPE3
  1022.                LODSW                           ;Start low word
  1023.                MOV     CS:FILE_POINTER[0],AX
  1024.                LODSW                           ;Start high word
  1025.                MOV     CS:FILE_POINTER[2],AX
  1026.                ADD     DI,4
  1027.                MOV     CX,SIZE PRODUCT_TYPE + SIZE WP_FILE_TYPE
  1028.                REPZ    CMPSB
  1029.                JNZ     GET_TYPE3
  1030.                INC     SI
  1031.                INC     SI
  1032.                INC     DI
  1033.                INC     DI
  1034.                CMPSB                           ;Encryption Key.
  1035.                JNZ     GET_TYPE3
  1036.  
  1037.                POP     DS
  1038.                MOV     DX,OFFSET ASCIIZ_NAME
  1039.                MOV     AH,4EH
  1040.                INT     21H
  1041.                MOV     AX,WORD PTR DTA.SIZE_LOW
  1042.                MOV     FILE_END[0],AX
  1043.                MOV     AX,WORD PTR DTA.SIZE_HIGH
  1044.                MOV     FILE_END[2],AX
  1045.                JMP     READ_FILE
  1046.  
  1047. ;----------------;
  1048. ;Word
  1049.  
  1050. GET_TYPE3:     MOV     CS:FILE_TYPE,OFFSET DOCUMENT
  1051.                MOV     CS:FILE_LINE,OFFSET ASCII_LINES
  1052.                MOV     CS:WORDSTAR,0FFH
  1053.                CMP     CS:BYTES_READ,SIZE WORD_FIB
  1054.                JB      GET_TYPE4
  1055.                XOR     SI,SI
  1056.                MOV     DI,OFFSET WORD_FIB
  1057.                MOV     CX,6
  1058.                REPZ    CMPSB
  1059.                JNZ     GET_TYPE4
  1060.  ;              CMP     DS:fAsv,0              ;Only if temp file.
  1061. ;               JNZ     GET_TYPE4
  1062.                MOV     AX,DS:fcMac[0]
  1063.                MOV     DX,DS:fcMac[2]
  1064.  
  1065.                POP     DS
  1066.                MOV     FILE_END[0],AX
  1067.                MOV     FILE_END[2],DX
  1068.                MOV     FILE_POINTER[0],128
  1069.                MOV     FILE_POINTER[2],0
  1070.                JMP     READ_FILE
  1071.  
  1072. ;----------------;
  1073. GET_TYPE4:     MOV     CS:FILE_TYPE,OFFSET DOCUMENT
  1074.                MOV     CS:FILE_LINE,OFFSET QandA_LINES
  1075.                CMP     CS:BYTES_READ,SIZE QandA_HEADER
  1076.                JB      GET_TYPE5
  1077.                XOR     SI,SI
  1078.                MOV     DI,OFFSET QandA_HEADER
  1079.                MOV     CX,5
  1080.                REPZ    CMPSB
  1081.                JZ      GOT_QandA
  1082.                XOR     SI,SI
  1083.                MOV     DI,OFFSET sig2
  1084.                MOV     CX,5
  1085.                REPZ    CMPSB
  1086.                JNZ     GET_TYPE5
  1087.  
  1088. GOT_QandA:     MOV     AX,DS:reltxtloc[0]
  1089.                MOV     DX,DS:reltxtloc[2]
  1090.                MOV     CX,DS:txtsize[0]
  1091.                MOV     BX,DS:txtsize[2]
  1092.                POP     DS
  1093.                MOV     FILE_POINTER[0],AX
  1094.                MOV     FILE_POINTER[2],DX
  1095.                ADD     AX,CX
  1096.                ADC     DX,BX
  1097.                MOV     FILE_END[0],AX
  1098.                MOV     FILE_END[2],DX
  1099.                JMP     SHORT READ_FILE
  1100.  
  1101. ;----------------;
  1102. ; Insert other types here
  1103.  
  1104. GET_TYPE5:
  1105.  
  1106. ;----------------;
  1107. ; ASCII if not any other special type.
  1108.  
  1109.                POP     DS
  1110.                MOV     FILE_TYPE,OFFSET DOCUMENT
  1111.                MOV     FILE_LINE,OFFSET ASCII_LINES
  1112.                MOV     AL,WORDSTAR_MASK
  1113.                MOV     WORDSTAR,AL
  1114.  
  1115.                MOV     DX,OFFSET ASCIIZ_NAME
  1116.                MOV     AH,4EH
  1117.                INT     21H
  1118.                MOV     AX,WORD PTR DTA.SIZE_LOW
  1119.                MOV     FILE_END[0],AX
  1120.                MOV     AX,WORD PTR DTA.SIZE_HIGH
  1121.                MOV     FILE_END[2],AX
  1122.                MOV     FILE_POINTER[0],0
  1123.                MOV     FILE_POINTER[2],0
  1124.  
  1125. READ_FILE:     MOV     SI,FILEBUFF_SIZE * KILOBYTES / 2
  1126.                CALL    READ
  1127.                JNC     TYPE_END
  1128.                MOV     FILE_CURRENT,FALSE
  1129.  
  1130. TYPE_END:      RET
  1131.  
  1132. ;----------------------------------------------;
  1133. CLEAR_FILE:    PUSH    ES
  1134.                MOV     BP,LISTING_LEN
  1135.                MOV     DX,STATUS_REG           ;Retrieve status register.
  1136.                MOV     ES,VIDEO_SEG
  1137.                MOV     DI,FCOLUMN_START
  1138.                MOV     BP,LISTING_LEN
  1139.                MOV     BH,COLOR.W
  1140.                MOV     AL,SPACE
  1141.  
  1142. NEXT_CLEAR:    PUSH    DI
  1143.                MOV     CX,FCOLUMN_LEN
  1144. NEXT_CLEAR2:   CALL    WRITE_CHAR
  1145.                LOOP    NEXT_CLEAR2
  1146.                POP     DI
  1147.                ADD     DI,CRT_WIDTH
  1148.                DEC     BP
  1149.                JNZ     NEXT_CLEAR
  1150.                POP     ES
  1151.                RET
  1152.  
  1153. ;--------------------------------------------------------------;
  1154. ; INPUT: BP -> Source filename; OUTPUT: ASCIIZ_NAME = filename ;
  1155. ;--------------------------------------------------------------;
  1156. MAKE_FILENAME: PUSH    DS
  1157.                MOV     DS,FILENAME_SEG         ;DS:SI -> Source name.
  1158.                MOV     SI,BP
  1159.                MOV     DI,OFFSET MARK_NAME     ;Name storage.
  1160.                MOVSB                           ;Copy mark.
  1161.                MOV     CX,8                    ;8 characters of name.
  1162. NEXT_NAME:     LODSB
  1163.                CMP     AL,SPACE                ;End of name?
  1164.                JZ      EXTENSION2              ;If yes, do extension.
  1165.                STOSB
  1166.                LOOP    NEXT_NAME
  1167. EXTENSION2:    MOV     SI,BP                   ;Retrieve name start.
  1168.                ADD     SI,10                   ;Move to extension field.
  1169.                CMP     BYTE PTR [SI],SPACE     ;Is there any extension?
  1170.                JZ      NAME_DONE               ;If no, done.
  1171.                MOV     AL,"."                  ;Else, add delimiting dot.
  1172.                STOSB
  1173.                MOV     CX,3                    ;3 characters for extension.
  1174. NEXT_EXT:      LODSB
  1175.                CMP     AL,SPACE
  1176.                JZ      NAME_DONE
  1177.                STOSB
  1178.                LOOP    NEXT_EXT
  1179. NAME_DONE:     XOR     AL,AL                   ;ASCIIZ.
  1180.                STOSB
  1181.                POP     DS
  1182.                RET
  1183.  
  1184. ;----------------------------------------------;
  1185. REMOVE_CNT     DW      ?
  1186.  
  1187. REMOVE1_MSG    DB      " marked files",0
  1188. REMOVE2_MSG    DB      " to be deleted?",0
  1189. REMOVE3_MSG    DB      " Do you wish to delete?  Y/N",0
  1190.  
  1191. REMOVE_MARKS:  PUSH    DS
  1192.                MOV     DS,FILENAME_SEG
  1193.                XOR     SI,SI
  1194.                XOR     CX,CX
  1195.                JMP     SHORT NEXT_COUNT2
  1196.  
  1197. NEXT_COUNT:    ADD     SI,SIZE FILE_RECORD
  1198. NEXT_COUNT2:   CMP     SI,CS:LAST_ADDR
  1199.                JA      GOT_COUNT
  1200.                CMP     BYTE PTR [SI],RIGHT_ARROW
  1201.                JNZ     NEXT_COUNT
  1202.                INC     CX
  1203.                JMP     NEXT_COUNT
  1204.  
  1205. GOT_COUNT:     POP     DS
  1206.                JCXZ    MARKS_ERR
  1207.                MOV     REMOVE_CNT,CX
  1208.                MOV     SI,OFFSET REMOVE1_MSG
  1209.                CALL    REMOVE_QUERY
  1210.                JC      MARKS_END
  1211.  
  1212.                MOV     BAR_ADDR,0
  1213.                MOV     LISTING_ADDR,0
  1214.                JMP     SHORT NEXT_REMOVE3
  1215.  
  1216. NEXT_REMOVE:   CALL    GET_PARAMS
  1217.                CALL    LDOWN
  1218. NEXT_REMOVE2:  CALL    DISP_LISTING
  1219. NEXT_REMOVE3:  PUSH    DS
  1220.                MOV     DS,FILENAME_SEG
  1221.                MOV     SI,CS:BAR_ADDR
  1222.                CMP     BYTE PTR [SI],RIGHT_ARROW
  1223.                POP     DS
  1224.                JNZ     NEXT_REMOVE
  1225.                CALL    REMOVE_IT
  1226.                JC      MARKS_ERR
  1227.                CALL    CK_KEY
  1228.                JNZ     MARKS_END
  1229.                DEC     REMOVE_CNT
  1230.                JNZ     NEXT_REMOVE2
  1231.                JMP     SHORT MARKS_END
  1232.  
  1233. MARKS_ERR:     CALL    BEEP
  1234. MARKS_END:     CALL    HIDE_CURSOR
  1235.                CALL    DISPLAY_MENU
  1236.                CALL    DISP_FILE
  1237.                CALL    CLEAR_KEY
  1238.                RET
  1239.  
  1240. ;--------------;
  1241.  
  1242. REMOVE:        PUSH    DS
  1243.                MOV     SI,BAR_ADDR
  1244.                MOV     DS,FILENAME_SEG
  1245.                LODSW
  1246.                POP     DS
  1247.                CMP     AL,-1
  1248.                JZ      REMOVE_ERR
  1249.                CMP     AL,"<"
  1250.                JNZ     REMOVE2
  1251.                CMP     AH,"."
  1252.                JZ      REMOVE_ERR
  1253.  
  1254. REMOVE2:       MOV     BP,BAR_ADDR
  1255.                CALL    MAKE_FILENAME
  1256.                MOV     SI,OFFSET ASCIIZ_NAME
  1257.                CALL    REMOVE_QUERY
  1258.                JC      REMOVE_END
  1259.                CALL    REMOVE_IT
  1260.                JC      REMOVE_ERR
  1261.  
  1262.                MOV     FILE_CURRENT,FALSE
  1263.                CALL    DISP_LISTING
  1264.                CALL    DISP_FILE
  1265.                JMP     SHORT REMOVE_END
  1266.  
  1267. REMOVE_ERR:    CALL    BEEP
  1268. REMOVE_END:    CALL    HIDE_CURSOR
  1269.                CALL    DISPLAY_MENU
  1270.                RET
  1271.  
  1272. ;--------------;
  1273. ; INPUT: SI -> msg; REMOVE_CNT = count.
  1274. ; OUTPUT: CF = 1 if abort.
  1275.  
  1276. REMOVE_QUERY:  CALL    CLEAR_MENU
  1277.                CALL    MENU_OFFSET
  1278.                PUSH    ES
  1279.                PUSH    DI
  1280.                MOV     DX,STATUS_REG
  1281.                MOV     ES,VIDEO_SEG
  1282.                MOV     AL,SPACE
  1283.                CALL    WRITE_CHAR
  1284.  
  1285.                PUSH    SI
  1286.                CMP     SI,OFFSET REMOVE1_MSG
  1287.                JNZ     DO_MSG
  1288.                MOV     AX,REMOVE_CNT
  1289.                XOR     DX,DX
  1290.                CALL    DISP_STATS
  1291.  
  1292. DO_MSG:        POP     SI
  1293.                CALL    WRITE_LINE
  1294.                MOV     SI,OFFSET REMOVE2_MSG
  1295.                CALL    WRITE_LINE
  1296.                POP     DI
  1297.                ADD     DI,CRT_WIDTH
  1298.                MOV     SI,OFFSET REMOVE3_MSG
  1299.                CALL    WRITE_LINE
  1300.                POP     ES
  1301.  
  1302.                XOR     AH,AH
  1303.                INT     16H
  1304.                CMP     AH,Y_SCAN
  1305.                STC
  1306.                JNZ     QUERY_END
  1307.                CLC
  1308. QUERY_END:     RET
  1309.  
  1310. ;----------------------------------------------;
  1311. ; INPUT: DX:AX = number; DI -> Display
  1312.  
  1313. DISP_STATS:    MOV     BP,DX
  1314.                MOV     SI,AX
  1315.                XOR     CX,CX
  1316.                MOV     BX,10
  1317.                JMP     SHORT DO_DIV
  1318.  
  1319. NEXT_DIV:      CMP     CH,3
  1320.                JNZ     DO_DIV
  1321.                MOV     AL,","
  1322.                PUSH    AX
  1323.                XOR     CH,CH
  1324.                INC     CL
  1325.  
  1326. DO_DIV:        MOV     AX,BP
  1327.                XOR     DX,DX
  1328.                DIV     BX
  1329.                MOV     BP,AX
  1330.                MOV     AX,SI
  1331.                DIV     BX
  1332.                MOV     SI,AX
  1333.                MOV     AX,DX
  1334.                ADD     AL,"0"
  1335.                PUSH    AX
  1336.                ADD     CX,0101H
  1337.                OR      BP,BP
  1338.                JNZ     NEXT_DIV
  1339.                OR      SI,SI
  1340.                JNZ     NEXT_DIV
  1341.  
  1342.                XOR     CH,CH
  1343.     ;           SUB     DI,CX   ; Add this to right justify
  1344.      ;          SUB     DI,CX
  1345.                MOV     BH,COLOR.B
  1346.                MOV     DX,STATUS_REG
  1347. NEXT_WRITE:    POP     AX
  1348.                CALL    WRITE_CHAR
  1349.                LOOP    NEXT_WRITE
  1350.                RET
  1351.  
  1352. ;--------------;
  1353.  
  1354. REMOVE_IT:     MOV     BP,BAR_ADDR
  1355.                CALL    MAKE_FILENAME
  1356.                MOV     DX,OFFSET ASCIIZ_NAME
  1357.                XOR     CX,CX
  1358.                MOV     AX,4301H                ;Normal attribute.
  1359.                INT     21H
  1360.  
  1361.                PUSH    DS
  1362.                MOV     DS,FILENAME_SEG
  1363.                MOV     AL,DS:[BP]
  1364.                POP     DS
  1365.                CMP     AL,"<"
  1366.                MOV     AH,3AH                  ;RMDIR
  1367.                JZ      REMOVE_IT2
  1368.  
  1369.                MOV     AH,41H
  1370. REMOVE_IT2:    INT     21H
  1371.                JC      REMOVE_IT_END
  1372.                CMP     FAIL_FLAG,TRUE
  1373.                STC
  1374.                JZ      REMOVE_IT_END
  1375.                CALL    MOVE_RECS
  1376.                CLC
  1377. REMOVE_IT_END: RET
  1378.  
  1379. ;--------------;
  1380.  
  1381. MOVE_RECS:     PUSH    DS
  1382.                PUSH    ES
  1383.                MOV     DI,BAR_ADDR
  1384.                MOV     SI,DI
  1385.                ADD     SI,SIZE FILE_RECORD
  1386.                MOV     AX,FILENAME_SEG
  1387.                MOV     DS,AX
  1388.                MOV     ES,AX
  1389. NEXT_MOVE:     MOV     CX,SIZE FILE_RECORD / 2
  1390.                REP     MOVSW
  1391.                CMP     DI,CS:LAST_ADDR
  1392.                JNA     NEXT_MOVE
  1393.                POP     ES
  1394.                POP     DS
  1395.  
  1396.                MOV     CX,SIZE FILE_RECORD
  1397.                SUB     LAST_ADDR,CX
  1398.  
  1399.                MOV     AX,LAST_ADDR
  1400.                CMP     BAR_ADDR,AX
  1401.                JNA     MOVE_END
  1402.                SUB     BAR_ADDR,CX
  1403. MOVE_END:      RET
  1404.  
  1405. ;----------------------------------------------;
  1406. NEW_FILE:      CALL    CLEAR_MENU
  1407.                CALL    GET_NAME
  1408.                JC      NEW_END
  1409.                MOV     FILENAME,81H
  1410.                CALL    NEW_FILESPEC
  1411.                JC      NO_NEW
  1412.                MOV     FILE_CURRENT,FALSE
  1413.                MOV     BAR_ADDR,0
  1414.                MOV     LISTING_ADDR,0
  1415.                MOV     DIR_LEVEL,0
  1416.                CALL    DISP_DIR
  1417.                CALL    DISP_LISTING
  1418.                CALL    DISP_FILE
  1419.                JMP     SHORT NEW_END
  1420.  
  1421. NO_NEW:        CALL    BEEP
  1422.  
  1423. NEW_END:       CALL    HIDE_CURSOR
  1424.                CALL    DISPLAY_MENU
  1425.                RET
  1426.  
  1427. ;----------------------------------------------;
  1428. LAST_STATE     DW      ?
  1429. LAST_ZOOM      DB      SHORT_NAME
  1430.  
  1431. ZOOM:          MOV     AH,1
  1432.                JMP     SHORT DO_ZOOM
  1433. SHIFT_ZOOM:    MOV     AH,-1
  1434.  
  1435. DO_ZOOM:       MOV     AL,ZOOM_STATE
  1436.                MOV     BL,AL
  1437.                ADD     AL,AH
  1438.                JNL     CK_UPPER
  1439.                MOV     AL,FULL_FILE
  1440. CK_UPPER:      CMP     AL,FULL_FILE
  1441.                JBE     GOT_ZOOM
  1442.                MOV     AL,SHORT_NAME
  1443. GOT_ZOOM:      CALL    CHANGE_ZOOM
  1444.                RET
  1445.  
  1446. ;--------------;
  1447.  
  1448. CHANGE_ZOOM:   MOV     ZOOM_STATE,AL
  1449.                MOV     LAST_ZOOM,BL
  1450.                CMP     AL,FULL_FILE
  1451.                JNZ     DISP_ZOOM
  1452.                MOV     BX,STATE
  1453.                MOV     LAST_STATE,BX
  1454.                MOV     STATE,OFFSET FILE
  1455.  
  1456. DISP_ZOOM:     CMP     BL,FULL_FILE
  1457.                JNZ     DISP_ZOOM2
  1458.                MOV     BX,LAST_STATE
  1459.                MOV     STATE,BX
  1460.  
  1461. DISP_ZOOM2:    CALL    INIT_ZOOM
  1462.                CALL    DISP_LISTING
  1463.                CALL    DISP_FILE
  1464.                RET
  1465.  
  1466. ;----------------------------------------------;
  1467. SORT_DIR:      XOR     SORT_ORDER,DESCEND
  1468.                CALL    SORT
  1469.                CALL    DISPLAY_MENU
  1470.                MOV     FILE_CURRENT,FALSE
  1471.                CALL    DISP_LISTING
  1472.                CALL    DISP_FILE
  1473.                RET
  1474.  
  1475. ;----------------------------------------------;
  1476. DISP_LISTING:  PUSH    DS
  1477.                PUSH    ES
  1478.                MOV     DI,LCOLUMN_START
  1479.  
  1480.                MOV     SI,LISTING_ADDR
  1481.                MOV     BP,LISTING_LEN
  1482.  
  1483.                MOV     DX,STATUS_REG           ;Retrieve status register.
  1484.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  1485.                MOV     DS,FILENAME_SEG
  1486.  
  1487. NEXT_LISTING:  PUSH    DI
  1488.                MOV     CX,CS:LCOLUMN_LEN
  1489.                JCXZ    CK_LAST_LINE
  1490.  
  1491. DISPLAY_LINE:  MOV     BH,CS:COLOR.W
  1492.                CMP     BYTE PTR [SI],-1
  1493.                JZ      PAD_LISTING
  1494.                CMP     SI,CS:BAR_ADDR
  1495.                JZ      CK_BAR_COLOR
  1496.                CMP     CS:STATE,OFFSET FILE
  1497.                JZ      DISPLAY_LINE2
  1498.                MOV     BH,CS:COLOR.I
  1499.                JMP     SHORT DISPLAY_LINE2
  1500.  
  1501. CK_BAR_COLOR:  MOV     BH,CS:COLOR.C
  1502.                CMP     CS:STATE,OFFSET FILE
  1503.                JNZ     DISPLAY_LINE2
  1504.                MOV     BH,CS:COLOR.A
  1505.  
  1506. DISPLAY_LINE2: LODSB
  1507.                CALL    WRITE_CHAR
  1508.                LOOP    DISPLAY_LINE2
  1509.  
  1510.                ADD     SI,CS:LCOLUMN_BAL
  1511.  
  1512. CK_LAST_LINE:  POP     DI
  1513.                ADD     DI,CS:CRT_WIDTH
  1514.                DEC     BP
  1515.                JNZ     NEXT_LISTING
  1516.                POP     ES
  1517.                POP     DS
  1518.                RET
  1519.  
  1520. PAD_LISTING:   CALL    PAD_LINE
  1521.                JMP     SHORT CK_LAST_LINE
  1522.  
  1523. PAD_LINE:      MOV     AL,SPACE
  1524. PAD_LINE2:     CALL    WRITE_CHAR
  1525.                LOOP    PAD_LINE2
  1526.                RET
  1527.  
  1528. ;----------------------------------------------;
  1529. DISPLAY_FLAG   DB      TRUE
  1530. LINE_CNT       DW      ?                       ;Counter for display line.
  1531. LINE_MAX       EQU     80                      ;Maximum line length supported.
  1532. ROW_CNT        DW      ?
  1533.  
  1534. DISP_FILE:     PUSH    ES
  1535.                CMP     FILE_CURRENT,TRUE
  1536.                JZ      DISP_FILE2
  1537.                CALL    OPEN_FILE
  1538.                JC      DISP_FILE_END
  1539.  
  1540. DISP_FILE2:    MOV     BH,COLOR.I
  1541.                CMP     STATE,OFFSET FILE
  1542.                JZ      DISP_FILE3
  1543.                MOV     BH,COLOR.W
  1544.  
  1545. DISP_FILE3:    MOV     DX,STATUS_REG           ;Retrieve status register.
  1546.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  1547.                MOV     DI,FCOLUMN_START
  1548.                MOV     AX,LISTING_LEN
  1549.                MOV     LINE_CNT,AX
  1550.                CALL    [FILE_TYPE]
  1551.  
  1552. DISP_FILE_END: POP     ES
  1553.                RET
  1554.  
  1555. ;----------------------;
  1556. SUBDIRECTORY   DB      " is a Subdirectory"
  1557. SUBEND         DB      0
  1558. PRESS_ENTER    DB      " Press Enter to load its files.",0
  1559.  
  1560. ; INPUT: BH=COLOR; DI=FCOLUMN_START; SI=BUFFER_PTR; DX=STATUS_REG; ES=VIDEO_SEG
  1561.  
  1562. SUBDIR:        MOV     BP,LISTING_LEN
  1563.                CALL    BLANK_LINE
  1564.                PUSH    DI
  1565.                CALL    DISPLAY_NAME
  1566.  
  1567.                MOV     SI,OFFSET SUBEND
  1568.                CMP     BYTE PTR ASCIIZ_NAME,"."
  1569.                JZ      SUBDIR2
  1570.                MOV     SI,OFFSET SUBDIRECTORY
  1571. SUBDIR2:       CALL    WRITE_LINE
  1572.  
  1573.                MOV     AL,SPACE
  1574.                CALL    REPEAT_CHAR
  1575.                POP     DI
  1576.                ADD     DI,CRT_WIDTH
  1577.  
  1578.                PUSH    DI
  1579.                MOV     CX,FCOLUMN_LEN
  1580.                CALL    WRITE_LINE
  1581.                MOV     AL,SPACE
  1582.                CALL    REPEAT_CHAR
  1583.                POP     DI
  1584.                ADD     DI,CRT_WIDTH
  1585.                DEC     BP
  1586.                DEC     BP
  1587.                DEC     BP
  1588.  
  1589. NEXT_DIR:      CALL    BLANK_LINE
  1590.                DEC     BP
  1591.                JNZ     NEXT_DIR
  1592.                RET
  1593.  
  1594. ;--------------;
  1595. BLANK_LINE:    PUSH    DI
  1596.                MOV     CX,FCOLUMN_LEN
  1597.                CALL    PAD_LINE
  1598.                POP     DI
  1599.                ADD     DI,CRT_WIDTH
  1600.                RET
  1601.  
  1602. ;--------------;
  1603. DISPLAY_NAME:  MOV     CX,FCOLUMN_LEN
  1604.                MOV     AL,SPACE
  1605.                CALL    WRITE_CHAR
  1606.                DEC     CX
  1607.                MOV     SI,OFFSET ASCIIZ_NAME
  1608.                CMP     BYTE PTR [SI],"."
  1609.                JNZ     DISPLAY_NAME2
  1610.                MOV     SI,OFFSET PARENT
  1611. DISPLAY_NAME2: CALL    WRITE_LINE
  1612.                RET
  1613.  
  1614. ;-----------;
  1615. ; Keeps track of a variable length field in CX while writing string.
  1616. WRITE_LINE:    LODSB
  1617.                OR      AL,AL
  1618.                JZ      WRITE_LINE_END
  1619.                CALL    WRITE_CHAR
  1620.                LOOP    WRITE_LINE
  1621. WRITE_LINE_END:RET
  1622.  
  1623. ;--------------;
  1624. DUMMY_RET:     RET
  1625.  
  1626. ;----------------------------------------------;
  1627. EXECUTE        DB      " is an executable file.",0
  1628.  
  1629. EXECUTABLE:    MOV     BP,LISTING_LEN
  1630.                CALL    BLANK_LINE
  1631.                PUSH    DI
  1632.                CALL    DISPLAY_NAME
  1633.  
  1634.                MOV     SI,OFFSET EXECUTE
  1635.                CALL    WRITE_LINE
  1636.  
  1637.                MOV     AL,SPACE
  1638.                CALL    REPEAT_CHAR
  1639.                POP     DI
  1640.                ADD     DI,CRT_WIDTH
  1641.  
  1642.                DEC     BP
  1643.                DEC     BP
  1644.  
  1645. NEXT_EXEC:     CALL    BLANK_LINE
  1646.                DEC     BP
  1647.                JNZ     NEXT_EXEC
  1648.                RET
  1649.  
  1650. ;----------------------------------------------;
  1651. DOCUMENT:      PUSH    DS
  1652.                MOV     SI,CURRENT_PAGE
  1653.                MOV     DISPLAY_FLAG,0
  1654.                MOV     CX,ROW
  1655.                MOV     ROW_CNT,CX
  1656.                MOV     DS,FILEBUFF_SEG
  1657.                JCXZ    NEXT_DOC
  1658. DOC_ROW:       CALL    CS:[FILE_LINE]
  1659.                DEC     CS:ROW_CNT
  1660.                JNZ     DOC_ROW
  1661.  
  1662. NEXT_DOC:      PUSH    DI
  1663.                MOV     CS:DISPLAY_FLAG,TRUE
  1664.                CALL    CS:[FILE_LINE]
  1665.                POP     DI
  1666.                ADD     DI,CS:CRT_WIDTH
  1667.                DEC     CS:LINE_CNT
  1668.                JNZ     NEXT_DOC
  1669.                POP     DS
  1670.                RET
  1671.  
  1672. ;------------------;
  1673. MULTI_BYTE     DB      0
  1674. VARI_WORD      DW      ?
  1675.  
  1676. WP_LINES:      MOV     CX,LINE_MAX
  1677.                MOV     BP,CS:FCOLUMN_LEN
  1678.  
  1679. WP_LINES2:     CMP     SI,CS:BUFFER_END
  1680.                JNZ     WP_CHAR
  1681.                CMP     CS:EOF_FLAG,TRUE
  1682.                JZ      WP_PAD
  1683.                MOV     CS:BUFFER_PTR,SI
  1684.                CALL    FORWARD
  1685.                JC      WP_END
  1686.                MOV     SI,CS:BUFFER_PTR
  1687.  
  1688. WP_CHAR:       LODSB
  1689.                CMP     CS:MULTI_BYTE,0
  1690.                JNZ     FIND_MULTI
  1691.                CMP     AL,CR
  1692.                JZ      WP_PAD
  1693.                CMP     AL,LF
  1694.                JZ      WP_PAD
  1695.                CMP     AL,SPACE
  1696.                JB      WP_LINES2
  1697.                CMP     AL,80H
  1698.                JB      GOOD_WP
  1699.  
  1700.                CMP     AL,0C0H
  1701.                JB      WP_LINES2
  1702.                CMP     AL,0D0H
  1703.                JAE     VARIABLE_BYTE
  1704.                MOV     CS:MULTI_BYTE,AL
  1705.                JMP     WP_LINES2
  1706.  
  1707. GOOD_WP:       PUSH    CX
  1708.                MOV     CX,1
  1709.                CALL    CK_WP_DISP
  1710.                POP     CX
  1711.                LOOP    WP_LINES2
  1712.                CALL    CK_BUFF
  1713.                JC      WP_END
  1714.                CMP     BYTE PTR [SI],CR
  1715.                JNZ     WP_END
  1716.                CMP     BYTE PTR [SI],LF
  1717.                JNZ     WP_END
  1718.                INC     SI
  1719. WP_END:        RET
  1720.  
  1721. FIND_MULTI:    CMP     AL,CS:MULTI_BYTE
  1722.                JNZ     WP_LINES2
  1723.                MOV     CS:MULTI_BYTE,0
  1724.                JMP     WP_LINES2
  1725.  
  1726. WP_PAD:        MOV     AL,SPACE
  1727. CK_WP_DISP:    CMP     CS:DISPLAY_FLAG,TRUE
  1728.                JNZ     CK_WP_END
  1729.                MOV     BL,AL
  1730. WP_WRITE:      CALL    WRITE_CHAR
  1731.                DEC     BP
  1732.                JNZ     WP_LOOP
  1733.                MOV     CS:DISPLAY_FLAG,FALSE
  1734. WP_LOOP:       LOOP    CK_WP_DISP
  1735. CK_WP_END:     RET
  1736.  
  1737. VARIABLE_BYTE: CMP     SI,CS:BUFFER_END
  1738.                JNZ     VAR_SUBFUNC
  1739.                CMP     CS:EOF_FLAG,TRUE
  1740.                JZ      VARIABLE_END
  1741.                MOV     CS:BUFFER_PTR,SI
  1742.                CALL    FORWARD
  1743.                JC      WP_END
  1744.                MOV     SI,CS:BUFFER_PTR
  1745.  
  1746. VAR_SUBFUNC:   LODSB
  1747.                CMP     SI,CS:BUFFER_END
  1748.                JNZ     VAR_SIZE1
  1749.                CMP     CS:EOF_FLAG,TRUE
  1750.                JZ      VARIABLE_END
  1751.                MOV     CS:BUFFER_PTR,SI
  1752.                CALL    FORWARD
  1753.                JC      WP_END
  1754.                MOV     SI,CS:BUFFER_PTR
  1755.  
  1756. VAR_SIZE1:     LODSB
  1757.                MOV     CS:BYTE PTR VARI_WORD[0],AL
  1758.                CMP     SI,CS:BUFFER_END
  1759.                JNZ     VAR_SIZE2
  1760.                CMP     CS:EOF_FLAG,TRUE
  1761.                JZ      VARIABLE_END
  1762.                MOV     CS:BUFFER_PTR,SI
  1763.                CALL    FORWARD
  1764.                JNC     VAR_SIZE2
  1765.                JMP     WP_END
  1766.                MOV     SI,CS:BUFFER_PTR
  1767.  
  1768. VAR_SIZE2:     LODSB
  1769.                MOV     CS:BYTE PTR VARI_WORD[1],AL
  1770.  
  1771. READ_VAR:      CMP     SI,CS:BUFFER_END
  1772.                JNZ     READ_VAR2
  1773.                CMP     CS:EOF_FLAG,TRUE
  1774.                JZ      VARIABLE_END
  1775.                MOV     CS:BUFFER_PTR,SI
  1776.                CALL    FORWARD
  1777.                JNC     READ_VAR2
  1778.                JMP     WP_END
  1779. READ_VAR2:     LODSB
  1780.                DEC     CS:VARI_WORD
  1781.                JNZ     READ_VAR
  1782.  
  1783. VARIABLE_END:  JMP     WP_LINES2
  1784.  
  1785. ;--------------;
  1786. FF_CODE        DB      0
  1787.  
  1788. QandA_LINES:   MOV     CX,LINE_MAX
  1789.                MOV     BP,CS:FCOLUMN_LEN
  1790.  
  1791. QandA_LINES2:  CMP     SI,CS:BUFFER_END
  1792.                JNZ     QandA_CHAR
  1793.                CMP     CS:EOF_FLAG,TRUE
  1794.                JZ      QandA_PAD
  1795.                MOV     CS:BUFFER_PTR,SI
  1796.                CALL    FORWARD
  1797.                JC      QandA_END
  1798.                MOV     SI,CS:BUFFER_PTR
  1799.  
  1800. QandA_CHAR:    LODSB
  1801.                CMP     CS:FF_CODE,0
  1802.                JNZ     FIND_FF_CODE
  1803.                CMP     AL,0FFH
  1804.                JNZ     GOOD_QandA
  1805.                MOV     CS:FF_CODE,AL
  1806.                JMP     QandA_LINES2
  1807.  
  1808. GOOD_QandA:    PUSH    CX
  1809.                MOV     CX,1
  1810.                CALL    CK_QandA_DISP
  1811.                POP     CX
  1812.                LOOP    QandA_LINES2
  1813.                CALL    CK_BUFF
  1814.                JC      QandA_END
  1815.                LODSB
  1816.                CMP     AL,0FFH
  1817.                JZ      CK_CR
  1818.                DEC     SI
  1819.                JMP     SHORT QandA_END
  1820. CK_CR:         CALL    CK_BUFF
  1821.                JC      QandA_END
  1822.                LODSB
  1823.                CMP     AL,1       ;CR
  1824.                JZ      QandA_END
  1825.                DEC     SI
  1826.                DEC     SI
  1827. QandA_END:     RET
  1828.  
  1829. FIND_FF_CODE:  MOV     AH,CS:FF_CODE
  1830.                CMP     AH,0FFH
  1831.                JZ      FIND_FF_CODE2
  1832.                DEC     CS:FF_CODE
  1833.                JMP     QandA_LINES2
  1834.  
  1835. FIND_FF_CODE2: CMP     AL,1
  1836.                JNZ     FIND_FF_CODE3
  1837.                MOV     CS:FF_CODE,0
  1838.                JMP     SHORT QandA_PAD
  1839. FIND_FF_CODE3: XOR     AL,AL
  1840.                XOR     AH,32
  1841.                CMP     AH,32
  1842.                JBE     FOUND_FF
  1843.                MOV     AL,2
  1844. FOUND_FF:      JMP     QandA_LINES2
  1845.  
  1846.  
  1847. QandA_PAD:     MOV     AL,SPACE
  1848. CK_QandA_DISP: CMP     CS:DISPLAY_FLAG,TRUE
  1849.                JNZ     CK_QandA_END
  1850.                MOV     BL,AL
  1851. QandA_WRITE:   CALL    WRITE_CHAR
  1852.                DEC     BP
  1853.                JNZ     QandA_LOOP
  1854.                MOV     CS:DISPLAY_FLAG,FALSE
  1855. QandA_LOOP:    LOOP    CK_QandA_DISP
  1856. CK_QandA_END:  RET
  1857.  
  1858. ;--------------;
  1859. ASCII_LINES:   MOV     CX,LINE_MAX
  1860.                MOV     BP,CS:FCOLUMN_LEN
  1861.  
  1862. ASCII_LINES2:  CMP     SI,CS:BUFFER_END
  1863.                JNZ     ASCII_CHAR
  1864.                CMP     CS:EOF_FLAG,TRUE
  1865.                JZ      ASCII_PAD
  1866.                MOV     CS:BUFFER_PTR,SI
  1867.                CALL    FORWARD
  1868.                JC      ASCII_END
  1869.                MOV     SI,CS:BUFFER_PTR
  1870.  
  1871. ASCII_CHAR:    LODSB
  1872.                AND     AL,CS:WORDSTAR
  1873.                CMP     AL,CR
  1874.                JZ      ASCII_PAD
  1875.                CMP     AL,TAB
  1876.                JZ      ASCII_TAB
  1877.                CMP     AL,LF
  1878.                JZ      ASCII_LINES2
  1879.                PUSH    CX
  1880.                MOV     CX,1
  1881.                CALL    CK_ASCII_DISP
  1882.                POP     CX
  1883.                LOOP    ASCII_LINES2
  1884.                CALL    CK_BUFF
  1885.                JC      ASCII_END
  1886.                CMP     BYTE PTR [SI],CR
  1887.                JNZ     ASCII_END
  1888.                INC     SI
  1889. ASCII_END:     RET
  1890.  
  1891. ASCII_TAB:     PUSH    CX
  1892.                DEC     CX
  1893.                AND     CX,7
  1894.                INC     CX
  1895.                PUSH    CX
  1896.                CALL    ASCII_PAD
  1897.                POP     AX
  1898.                POP     CX
  1899.                SUB     CX,AX
  1900.                JNZ     ASCII_LINES2
  1901.                JMP     ASCII_END
  1902.  
  1903. ASCII_PAD:     MOV     AL,SPACE
  1904. CK_ASCII_DISP: CMP     CS:DISPLAY_FLAG,TRUE
  1905.                JNZ     CK_ASCII_END
  1906.                MOV     BL,AL
  1907. ASCII_WRITE:   CALL    WRITE_CHAR
  1908.                DEC     BP
  1909.                JNZ     ASCII_LOOP
  1910.                MOV     CS:DISPLAY_FLAG,FALSE
  1911. ASCII_LOOP:    LOOP    CK_ASCII_DISP
  1912. CK_ASCII_END:  RET
  1913.  
  1914. ;--------------;
  1915. CK_BUFF:       CMP     SI,CS:BUFFER_END
  1916.                CLC
  1917.                JNZ     CK_BUFF_END
  1918.                CMP     CS:EOF_FLAG,TRUE
  1919.                STC
  1920.                JZ      CK_BUFF_END
  1921.                MOV     CS:BUFFER_PTR,SI
  1922.                CALL    FORWARD
  1923.                MOV     SI,CS:BUFFER_PTR
  1924. CK_BUFF_END:   RET
  1925.  
  1926. ;----------------------------------------------;
  1927. DIRECTORY      DB      "    Directory of ",0
  1928.  
  1929. DISP_DIR:      PUSH    ES
  1930.                MOV     SI,OFFSET WORKING_DIR
  1931.                CALL    GET_DIR
  1932.  
  1933.                MOV     DX,STATUS_REG           ;Retrieve status register.
  1934.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  1935.                MOV     BH,COLOR.B
  1936.                MOV     DI,CRT_WIDTH
  1937.                MOV     CX,DI
  1938.                SHR     CX,1
  1939.  
  1940.                MOV     SI,OFFSET DIRECTORY
  1941.                CALL    WRITE_LINE
  1942.                MOV     AL,WORKING_DRIVE
  1943.                ADD     AL,"A"
  1944.                CALL    WRITE_CHAR
  1945.                DEC     CX
  1946.                MOV     AL,":"
  1947.                CALL    WRITE_CHAR
  1948.                DEC     CX
  1949.                MOV     SI,OFFSET WORKING_DIR
  1950.                CALL    WRITE_LINE
  1951.                CALL    PAD_LINE
  1952.                POP     ES
  1953.                RET
  1954.  
  1955. ;----------------------------------------------;
  1956. ENTER:         MOV     BP,BAR_ADDR
  1957.                CALL    MAKE_FILENAME
  1958.                CMP     MARK_NAME,"<"
  1959.                JNZ     DO_ZOOM2
  1960.  
  1961.                PUSH    WORD PTR ASCIIZ_NAME
  1962.                MOV     FILENAME,OFFSET ASCIIZ_NAME
  1963.                CALL    NEW_FILESPEC
  1964.                POP     AX
  1965.  
  1966.                CMP     AL,"."                  ;Parent dir?
  1967.                JNZ     NEXT_LEVEL
  1968.                CMP     DIR_LEVEL,0
  1969.                JZ      NEXT_LEVEL
  1970.  
  1971.                DEC     DIR_LEVEL
  1972.                MOV     BX,DIR_LEVEL
  1973.                SHL     BX,1
  1974.                SHL     BX,1
  1975.                MOV     AX,DIR_POINTERS.TOP_LOC[BX]
  1976.                MOV     LISTING_ADDR,AX
  1977.                MOV     AX,DIR_POINTERS.BAR_LOC[BX]
  1978.                MOV     BAR_ADDR,AX
  1979.                CMP     AX,LAST_ADDR
  1980.                JBE     SHORT UPDATE_DISP
  1981.                MOV     DIR_LEVEL,0
  1982.                JMP     SHORT HOME_BAR
  1983.  
  1984. NEXT_LEVEL:    MOV     BX,DIR_LEVEL
  1985.                CMP     BX,DIR_LEVEL_MAX
  1986.                JZ      HOME_BAR
  1987.                SHL     BX,1
  1988.                SHL     BX,1
  1989.                MOV     AX,LISTING_ADDR
  1990.                MOV     DIR_POINTERS.TOP_LOC[BX],AX
  1991.                MOV     AX,BAR_ADDR
  1992.                MOV     DIR_POINTERS.BAR_LOC[BX],AX
  1993.                INC     DIR_LEVEL
  1994. HOME_BAR:      MOV     BAR_ADDR,0
  1995.                MOV     LISTING_ADDR,0
  1996.  
  1997. UPDATE_DISP:   CALL    DISP_DIR
  1998.                CALL    DISP_LISTING
  1999.                CALL    DISP_FILE
  2000.                JMP     SHORT LOAD_END
  2001.  
  2002. DO_ZOOM2:      MOV     AL,LAST_ZOOM
  2003.                MOV     BL,ZOOM_STATE
  2004.                CMP     BL,FULL_FILE
  2005.                JZ      DO_ZOOM3
  2006.                MOV     AL,FULL_FILE
  2007. DO_ZOOM3:      CALL    CHANGE_ZOOM
  2008.  
  2009. LOAD_END:      RET
  2010.  
  2011.  
  2012. ;------------------------------------------------------------------;
  2013. ; Parse drive and/or path delimiters.  Convert filespec to ASCIIZ. ;
  2014. ; If drive delimiter found (:), change to requested drive.         ;
  2015. ;------------------------------------------------------------------;
  2016. ; OUTPUT: CY=1 if invalid filespec.
  2017.  
  2018. NEW_FILESPEC:  MOV     SI,FILENAME
  2019. PARSE_LEADING: LODSB                           ;Get a byte.
  2020.                CMP     AL,SPACE                ;Is it a space char or below?
  2021.                JA      LEADING_END             ;If no, done here.
  2022.                CMP     AL,CR                   ;Is it carriage return?
  2023.                JNZ     PARSE_LEADING           ;If no, get next byte.
  2024. LEADING_END:   DEC     SI                      ;Adjust pointer to string start.
  2025.                MOV     BP,SI                   ;Save start of filespec.
  2026.                MOV     BX,SI                   ;Use BX as filename start pointer
  2027.  
  2028. FIND_END:      LODSB                           ;Get a byte.
  2029.                CMP     AL,":"                  ;Is it a drive delimiter?
  2030.                JNZ     CK_SLASH                ;If no, check path delimiter.
  2031.                CALL    RESTORE_DIR
  2032.                MOV     DL,[SI-2]               ;Else, retrieve drive specifier.
  2033.                AND     DL,5FH                  ;Capitalize.
  2034.                SUB     DL,"A"                  ;Convert to DOS format.
  2035.                MOV     WORKING_DRIVE,DL
  2036.                MOV     AH,0EH                  ;Change drive.
  2037.                INT     21H
  2038.                PUSH    SI
  2039.                MOV     SI,OFFSET CURRENT_DIR
  2040.                CALL    GET_DIR
  2041.                POP     SI
  2042.                MOV     BX,SI                   ;Save as filename start.
  2043.                JMP     FIND_END                ;Continue parsing.
  2044.  
  2045. CK_SLASH:      CMP     AL,"\"                  ;Is it a path delimiter?
  2046.                JNZ     CK_DELIMITER            ;If no, check switch character.
  2047.                MOV     BX,SI                   ;Else, save as filename start.
  2048. CK_DELIMITER:  CMP     AL,"/"                  ;Is it a switch delimiter?
  2049.                JZ      FOUND_END               ;If yes, end of filespec.
  2050.                CMP     AL,SPACE                ;Is it above space character?
  2051.                JA      FIND_END                ;If yes, continue until find end.
  2052.  
  2053. FOUND_END:     DEC     SI                      ;Adjust.
  2054.                MOV     FILESPEC_END,SI
  2055.                PUSH    [SI]
  2056.                MOV     BYTE PTR [SI],0         ;Convert to ASCIIZ.
  2057.  
  2058. ;-------------------------------------------------;
  2059. FIND_PATH:     CMP     BP,SI                   ;No filespec?
  2060.                JZ      GLOBAL
  2061.                CMP     BYTE PTR [SI - 1],":"   ;Drive-only filespec?
  2062.                JZ      GLOBAL
  2063.  
  2064. CK_ROOT:       MOV     CX,1                    ;CX=1:"\"not=root; CX=0:"\"=root.
  2065.                CMP     BYTE PTR [BX - 1],"\"   ;Filespec start path delimiter?
  2066.                JNZ     CK_PATH                 ;If no, not root.
  2067.                CMP     BYTE PTR [BX - 2],":"   ;Else, is it prefaced with colon?
  2068.                JZ      ROOT                    ;If yes, then root.
  2069.                CMP     BYTE PTR [BX - 2],SPACE ;Is it prefaced with white space?
  2070.                JA      CK_TRAILING             ;If no, then trailing slash?
  2071. ROOT:          DEC     CX                      ;Else, root; CX=0 for root flag.
  2072.                JMP     SHORT CK_PATH           ;Change default path.
  2073.  
  2074. CK_TRAILING:   CMP     BX,SI                   ;Filename start = filespec end?
  2075.                JNZ     CK_PATH                 ;If no, not trailing slash.
  2076.                MOV     BYTE PTR [BX - 1],0     ;Else, zero out trailing slash
  2077.                MOV     BX,OFFSET STAR_DOT_STAR ; and use global filespec.
  2078.  
  2079. CK_PATH:       MOV     DX,BP                   ;See if filespec is a path
  2080.                CALL    CHANGE_DIR              ; by changing directory.
  2081.                JC      CK_FILESPEC             ;If failed, remove filename.
  2082. GLOBAL:        MOV     BX,OFFSET STAR_DOT_STAR ;Else, use global for filename.
  2083.                JMP     SHORT GOT_FILESPEC      ;Done here.
  2084.  
  2085. CK_FILESPEC:   JCXZ    SAVE_DELIMIT            ;Is path root?; If yes leave "\".
  2086.                DEC     BX                      ;Else, point to slash.
  2087. SAVE_DELIMIT:  PUSH    [BX]                    ;Preserve filename start.
  2088.                MOV     BYTE PTR [BX],0         ;Temp ASCIIZ twixt path and name.
  2089.                CALL    CHANGE_DIR              ;Change directory.
  2090.                POP     [BX]                    ;Restore first byte of filename.
  2091.                JCXZ    GOT_FILESPEC            ;If root, done here.
  2092.                INC     BX                      ;Else, readjust filename pointer.
  2093. GOT_FILESPEC:  MOV     FILESPEC,BX             ;Save filename.
  2094.                POP     [SI]
  2095.  
  2096.                CALL    PARSE
  2097.                JC      NEW_FILE_END
  2098.                CALL    FIND_FILES
  2099. NEW_FILE_END:  RET
  2100.  
  2101. ;----------------------------------------------;
  2102. ; OUTPUT: CF=1 if no files found.
  2103.  
  2104. FIND_FILES:    PUSH    ES                      ;Preserve extra segment.
  2105.                MOV     ES,FILENAME_SEG         ;ES:DI -> filename storage.
  2106.                XOR     DI,DI
  2107.                MOV     DX,FILESPEC
  2108.  
  2109.                MOV     CX,ATTR
  2110.                MOV     AH,4EH                  ;Find first.
  2111.                MOV     SI,FILESPEC_END
  2112.                PUSH    [SI]
  2113.                MOV     BYTE PTR [SI],0
  2114.                INT     21H                     ;Any files?
  2115.                POP     [SI]
  2116.                JNC     FIND_FILES2
  2117.                CALL    RESTORE_DIR
  2118.                MOV     DL,DEFAULT_DRIVE
  2119.                MOV     AH,0EH
  2120.                INT     21H
  2121.                MOV     DX,OFFSET NOT_FOUND
  2122.                STC
  2123.                JMP     SHORT FILES_END
  2124.  
  2125. FIND_FILES2:   MOV     AX,SPACE SHL 8 + SPACE
  2126.                MOV     CX,FILENAME_SIZE / 2 * KILOBYTES
  2127.                REP     STOSW                   ;Initialize with spaces.
  2128.                XOR     DI,DI
  2129.  
  2130. FIND_NEXT:     CALL    STORE_NAME              ;Store a filename.
  2131.                CMP     DI,TEMP_RECORD - SIZE FILE_RECORD
  2132.                JA      FILES_DONE
  2133.                MOV     AH,4FH                  ;Find Next Matching.
  2134.                INT     21H
  2135.                JNC     FIND_NEXT               ;If successful store filename.
  2136.  
  2137. FILES_DONE:    MOV     AX,-1                   ;Else, mark the end with -1.
  2138.                STOSW
  2139.                SUB     DI,SIZE FILE_RECORD + 2
  2140.                JNC     STORE_LAST
  2141.                XOR     DI,DI
  2142. STORE_LAST:    MOV     LAST_ADDR,DI
  2143.                CALL    SORT                    ;Sort 'em.
  2144.                CLC
  2145. FILES_END:     POP     ES                      ;Restore extra segment.
  2146.                RET
  2147.  
  2148. ;----------------------------------------------;
  2149. READ_ONLY      EQU     01H
  2150. HIDDEN         EQU     02H
  2151. SUB_DIR        EQU     10H
  2152. NOT_MODIFIED   EQU     00H
  2153. MODIFIED       EQU     20H
  2154. IGNORE         EQU     -1
  2155. MODIFIED_TYPE  DB      IGNORE
  2156.  
  2157. PRIOR          EQU     0
  2158. AFTER          EQU     1
  2159. DATE_FLAG      DB      IGNORE
  2160. FILEDATE       DW      ?
  2161.  
  2162.  
  2163. STORE_NAME:    MOV     AL,DTA.ATTRIBUTE
  2164.                TEST    AL,READ_ONLY
  2165.                JZ      STORE_NAME2
  2166.                TEST    ATTR,READ_ONLY
  2167.                JZ      LILLY_END
  2168.  
  2169. STORE_NAME2:   TEST    AL,SUB_DIR
  2170.                JNZ     STORE_NAME4
  2171.                CMP     MODIFIED_TYPE,IGNORE
  2172.                JZ      STORE_NAME3
  2173.                AND     AL,MODIFIED
  2174.                CMP     AL,MODIFIED_TYPE
  2175.                JNZ     LILLY_END
  2176.  
  2177. STORE_NAME3:   CMP     DATE_FLAG,IGNORE
  2178.                JZ      STORE_NAME4
  2179.                MOV     AX,FILEDATE
  2180.                CMP     DATE_FLAG,PRIOR
  2181.                JZ      CK_PRIOR
  2182.                CMP     DTA.FILE_DATE,AX
  2183.                JAE     STORE_NAME4
  2184.                JMP     SHORT LILLY_END
  2185.  
  2186. CK_PRIOR:      CMP     DTA.FILE_DATE,AX
  2187.                JBE     STORE_NAME4
  2188.                JMP     SHORT LILLY_END
  2189.  
  2190. STORE_NAME4:   MOV     SI,OFFSET DTA.FILE_NAME ;Point to filename.
  2191.                INC     DI                      ;Bump past Mark.
  2192.  
  2193.                MOV     CX,SIZE LIST_NAME       ;Store 12 bytes of filename.
  2194.                CMP     BYTE PTR [SI],"."
  2195.                JNZ     NEXT_STORE
  2196.                CMP     BYTE PTR [SI+1],"."
  2197.                JZ      STORE_DOTDOT
  2198.                DEC     DI
  2199. LILLY_END:     JMP     STORE_NAME_END
  2200.  
  2201. STORE_DOTDOT:  LODSB
  2202.                STOSB
  2203.                STOSB
  2204.                ADD     DI,SIZE LIST_NAME - 2
  2205.                JMP     SHORT CK_DIR
  2206.  
  2207. EXTENSION:     ADD     DI,CX
  2208.                MOV     CX,3
  2209.                SUB     DI,CX
  2210.  
  2211. NEXT_STORE:    LODSB                           ;Get a byte.
  2212.                OR      AL,AL                   ;End of filename?
  2213.                JZ      END_STORE               ;If yes, finish with blanks.
  2214.                CMP     AL,"."                  ;Is it the period?
  2215.                JZ      EXTENSION
  2216.  
  2217.                STOSB                           ;Store byte.
  2218.                LOOP    NEXT_STORE              ;Get next byte.
  2219. END_STORE:     ADD     DI,CX
  2220.  
  2221. CK_DIR:        MOV     BX,10                   ;Convert to decimal.
  2222.                TEST    DTA.ATTRIBUTE,10H
  2223.                JZ      STORE_SIZE
  2224.                MOV     BYTE PTR ES:[DI-SIZE LIST_NAME-SIZE MARK],"<"
  2225.                MOV     BYTE PTR ES:[DI],">"
  2226.                ADD     DI,SIZE LIST_DATE
  2227.                JMP     SHORT STORE_DATE
  2228.  
  2229. STORE_SIZE:    PUSH    DI                      ;Save pointer.
  2230.                ADD     DI,SIZE LIST_BYTES      ;Move to end of bytes field.
  2231.                MOV     DX,DTA.SIZE_LOW         ;Retrieve high and low words
  2232.                MOV     AX,DTA.SIZE_HIGH        ; of size in bytes.
  2233.  
  2234.                STD                             ;Reverse direction.
  2235. NEXT_SIZE:     MOV     CX,DX                   ;Low word in CX.
  2236.                XOR     DX,DX                   ;Zero in high half.
  2237.                DIV     BX                      ;Convert to decimal.
  2238.                XCHG    AX,CX                   ;Retrieve low word.
  2239.                DIV     BX
  2240.                XCHG    AX,DX                   ;Retrieve remainder.
  2241.                ADD     AL,"0"                  ;Convert to ASCII.
  2242.                STOSB                           ;Store it.
  2243.                MOV     AX,CX                   ;Are we done?
  2244.                OR      CX,DX
  2245.                JNZ     NEXT_SIZE               ;If no, divide again.
  2246.  
  2247.                CLD                             ;Back to forward direction.
  2248.                POP     DI                      ;Retrieve pointer.
  2249.                ADD     DI,SIZE LIST_DATE       ;Move to date field.
  2250.  
  2251. STORE_DATE:    MOV     DX,DTA.FILE_DATE        ;Retrieve date.
  2252.                MOV     AX,DX
  2253.                MOV     CL,5                    ;Shift to lowest bits.
  2254.                SHR     AX,CL
  2255.                AND     AX,1111B                ;Mask off all but month.
  2256.                MOV     CL,0FFH                 ;Flag as no leading zeros.
  2257.                MOV     CH,"-"                  ;Delimiting character.
  2258.                CALL    STORE_WORD              ;Store it.
  2259.  
  2260.                MOV     AX,DX                   ;Retrieve date.
  2261.                AND     AX,11111B               ;Mask off all but day.
  2262.                XOR     CL,CL                   ;Flag include leading zeros.
  2263.                CALL    STORE_WORD              ;Store it.
  2264.  
  2265.                MOV     AX,DX                   ;Retrieve date for last time.
  2266.                MOV     CL,9
  2267.                SHR     AX,CL                   ;Mask off all but year.
  2268.                ADD     AX,80                   ;Adjust to ASCII.
  2269.                CMP     AX,100                  ;Past year 2000?
  2270.                JB      DISPLAY_DATE            ;If no, display. Else, adjust for
  2271.                SUB     AX,100                  ; next century. (Planning ahead!)
  2272. DISPLAY_DATE:  XOR     CL,CL                   ;Display leading zeros.
  2273.                MOV     CH,SPACE
  2274.                CALL    STORE_WORD              ;Store it.
  2275.  
  2276. TIME:          INC     DI                      ;Move to time field.
  2277.                MOV     DX,DTA.FILE_TIME        ;Retrieve time.
  2278.                MOV     AX,DX
  2279.                MOV     CL,11                   ;Shift to hours bits.
  2280.                SHR     AX,CL
  2281.                PUSH    AX
  2282.                CMP     AX,12                   ;Past noon?
  2283.                JBE     MERIDIAN
  2284.                SUB     AX,12                   ;If yes, adjust.
  2285. MERIDIAN:      CMP     AX,0                    ;Midnight?
  2286.                JNZ     NOT_MIDNIGHT
  2287.                MOV     AX,12                   ;If yes, adjust.
  2288. NOT_MIDNIGHT:  MOV     CL,0FFH                 ;Suppress leading zeros.
  2289.                MOV     CH,":"
  2290.                CALL    STORE_WORD              ;Store it.
  2291.  
  2292.                MOV     AX,DX                   ;Retrieve time.
  2293.                MOV     CL,5                    ;Shift to minutes bits.
  2294.                SHR     AX,CL
  2295.                AND     AX,111111B              ;Mask off all but minutes.
  2296.                XOR     CL,CL
  2297.                POP     DX                      ;Retrieve hours.
  2298.                MOV     CH,"p"                  ;Assume PM.
  2299.                CMP     DX,12                   ;Is it PM?
  2300.                JAE     PM
  2301.                MOV     CH,"a"                  ;If no, AM.
  2302.  
  2303. PM:            CALL    STORE_WORD              ;Store it.
  2304. STORE_NAME_END:RET                             ;Done here.
  2305.  
  2306. ;-----------------------------------------------------------------------;
  2307. ; Converts a two byte hex number to decimal followed by delimiter.      ;
  2308. ; INPUT: AX = hex number; BL = 10; CH = delimiter character to store.   ;
  2309. ;   CL = 0 if zeros are to be stored; CL = -1 if leading zeros ignored. ;
  2310. ;   ES:DI points to storage.                                            ;
  2311. ;-----------------------------------------------------------------------;
  2312. STORE_WORD:    DIV     BL                      ;Divide by ten.
  2313.                ADD     AX,"00"                 ;Convert to ASCII.
  2314.                CMP     CL,0                    ;Are we to display leading zero?
  2315.                JZ      STORE_IT                ;If yes, store as is.
  2316.                CMP     AL,"0"                  ;Is it a leading zero?
  2317.                JNZ     STORE_IT                ;If no, store it.
  2318.                MOV     AL,SPACE                ;Else, store a space.
  2319. STORE_IT:      STOSW
  2320.                MOV     AL,CH                   ;Store delimiter character also.
  2321.                STOSB
  2322.                RET
  2323.  
  2324. ;------------------------------------------------------------------------;
  2325. ; These four subroutines control in which column the sorting will start. ;
  2326. ;------------------------------------------------------------------------;
  2327. SORTS_CODE     DB      76H,  77H, 72H,   73H, 72H, 77H
  2328.                        ;JBE, JA,  JB     JAE, JB,  JA
  2329.  
  2330. SORT_TABLE     DW      1,12,  10,3,  14,8,  30,2
  2331.                        ;Name  Ext    Size   Date
  2332.                        ;offset,length
  2333.  
  2334. SORT_NAME:     MOV     BP,NAME_SORT
  2335.                JMP     SHORT STORE_SORT
  2336.  
  2337. SORT_EXT:      MOV     BP,EXT_SORT
  2338.                JMP     SHORT STORE_SORT
  2339.  
  2340. SORT_SIZE:     MOV     BP,SIZE_SORT
  2341.                JMP     SHORT STORE_SORT
  2342.  
  2343. SORT_DATE:     MOV     BP,DATE_SORT
  2344.  
  2345. STORE_SORT:    MOV     SORT_INDEX,BP
  2346.                CALL    SORT
  2347.                CALL    DISP_LISTING
  2348.                RET
  2349.  
  2350. ;---------------------------------------------------;
  2351. ; Insertion sort;  Doesn't destroy secondary sorts. ;
  2352. ;---------------------------------------------------;
  2353. SORT:          CMP     SORT_ORDER,NO_SORT
  2354.                JNZ     DO_SORT
  2355.                RET
  2356.  
  2357. DO_SORT:       MOV     SI,OFFSET SORTS_CODE
  2358.                ADD     SI,SORT_ORDER
  2359. MODIFY_CODE:   LODSB
  2360.                MOV     S1,AL
  2361.                LODSB
  2362.                MOV     S2,AL
  2363.                MOV     S3,AL
  2364.                MOV     S4,AL
  2365.                MOV     S6,AL
  2366.                MOV     S8,AL
  2367.                LODSB
  2368.                MOV     S5,AL
  2369.                MOV     S7,AL
  2370.  
  2371. ;----------------------------------------------;
  2372.  
  2373.                MOV     BP,SORT_INDEX           ;BP = Index in sort table field.
  2374.                MOV     BX,SORT_TABLE[BP]       ;BX = Sort field offset.
  2375.                INC     BP
  2376.                INC     BP
  2377.                MOV     BP,SORT_TABLE[BP]       ;BP = Sort field length
  2378.  
  2379.                XOR     SI,SI                   ;SI = First record.
  2380.                MOV     DI,SIZE FILE_RECORD     ;DI = Second record.
  2381.                PUSH    DS
  2382.                PUSH    ES
  2383.                MOV     ES,FILENAME_SEG
  2384.                MOV     DS,FILENAME_SEG
  2385.  
  2386.                CMP     BYTE PTR [SI],-1
  2387.                JZ      SORT_END
  2388.                CMP     BYTE PTR [DI],-1
  2389.                JZ      SORT_END
  2390.  
  2391. NEXT_SORT:     CMP     DI,CS:LAST_ADDR         ;Sort is done when last record.
  2392.                JA      SORT_END
  2393.  
  2394.                PUSH    SI                      ;Save record pointers.
  2395.                PUSH    DI
  2396.                MOV     AX,SI                   ;Carry source pointer in AX.
  2397.                MOV     DX,DI                   ;Carry destination pointer in DX.
  2398.  
  2399. NEXT_RECORD:   ADD     SI,BX                   ;Index to sort field.
  2400.                ADD     DI,BX
  2401.                MOV     CX,BP                   ;Field length.
  2402.                CMP     BP,2                    ;Sort by date is special case.
  2403.                JZ      DO_DATE
  2404. COMPARE:       REPZ    CMPSB                   ;Compare the fields.
  2405.  
  2406. S1 LABEL BYTE
  2407.                JBE     NO_SWITCH               ;If below or equal, no switch.
  2408.  
  2409. SWAP:          CMP     DX,TEMP_RECORD          ;Else, if DX points to temporary
  2410.                JZ      DO_SWAP                 ; storage, safe to move.
  2411.                MOV     SI,DX                   ;Else, move destination record
  2412.                MOV     DX,TEMP_RECORD          ; to temporary storage.
  2413.                MOV     DI,DX
  2414.                MOV     CX,SIZE FILE_RECORD / 2
  2415.                REP     MOVSW
  2416.  
  2417. DO_SWAP:       MOV     SI,AX                   ;Restore source pointer
  2418.                MOV     DI,SI                   ;Destination = source +
  2419.                ADD     DI,SIZE FILE_RECORD     ; field size.
  2420.                MOV     CX,SIZE FILE_RECORD / 2
  2421.                REP     MOVSW                   ;Move the record.
  2422.  
  2423.                MOV     DI,DX                   ;Prepare for next compare.
  2424.                SUB     AX,SIZE FILE_RECORD     ;Destination = temporary.
  2425.                MOV     SI,AX                   ;Move one record towards start.
  2426.                JNC     NEXT_RECORD
  2427.  
  2428. NO_SWITCH:     MOV     SI,TEMP_RECORD          ;If DX doesn't point to temporary
  2429.                CMP     DX,SI                   ; storage, no move was made; next
  2430.                JNZ     NEXT_INSERT             ; compare.
  2431.                MOV     DI,AX                   ;Else, move temporary record
  2432.                ADD     DI,SIZE FILE_RECORD     ; into last move location.
  2433.                MOV     CX,SIZE FILE_RECORD / 2
  2434.                REP     MOVSW
  2435.  
  2436. NEXT_INSERT:   POP     DI                      ;Restore outside loop pointers.
  2437.                POP     SI
  2438.                ADD     SI,SIZE FILE_RECORD     ;Move both source and destination
  2439.                ADD     DI,SIZE FILE_RECORD     ; to the next record.
  2440.                JMP     NEXT_SORT
  2441.  
  2442. SORT_END:      POP     ES
  2443.                POP     DS
  2444.                MOV     FILE_CURRENT,FALSE
  2445.                RET
  2446.  
  2447. ;------------------;
  2448.  
  2449. DO_DATE:       REPZ    CMPSB                   ;Compare year first.
  2450.  
  2451. S2 LABEL BYTE
  2452.                JA      SWAP                    ;If above, swap.
  2453.                JNZ     NO_SWITCH
  2454.                SUB     SI,8                    ;Else, adjust and do month/day.
  2455.                SUB     DI,8
  2456.                MOV     CX,5
  2457.                REPZ    CMPSB
  2458. S3 LABEL BYTE
  2459.                JA      SWAP                    ;If above, swap.
  2460.                JNZ     NO_SWITCH
  2461.                ADD     SI,10                   ;Else, adjust and do meridian.
  2462.                ADD     DI,10
  2463.                CMPSB
  2464. S4 LABEL BYTE
  2465.                JA      SWAP                    ;If above, swap.
  2466.                JNZ     NO_SWITCH
  2467.                SUB     SI,6                    ;Else, adjust and do time.
  2468.                SUB     DI,6
  2469.                MOV     CX,5
  2470.                CMP     WORD PTR [SI],3231H     ;Is it special case "12:"?
  2471.                JZ      CK_MERIDIAN             ;If yes, see if same.
  2472.                CMP     WORD PTR [DI],3231H     ;Is destination "12:"?
  2473.                JNZ     DATE_END                ;If no, normal compare.
  2474. CK_MERIDIAN:   CMPSB                           ;Are both "12:"?
  2475.  
  2476. S5 LABEL BYTE
  2477.                JB      LONG_JMP                ;Swap
  2478. S6 LABEL BYTE
  2479.                JA      NO_SWITCH
  2480.  
  2481.                CMPSB
  2482. S7 LABEL BYTE
  2483.                JB      LONG_JMP
  2484. S8 LABEL BYTE
  2485.                JA      NO_SWITCH
  2486.  
  2487.                MOV     CX,3                    ;Else compare minutes.
  2488. DATE_END:      JMP     COMPARE
  2489. LONG_JMP:      JMP     SWAP
  2490.  
  2491. ;----------------------------------------------;
  2492. ; OUTPUT: CF=1 if illegal parameter.
  2493.  
  2494. PARSE:         MOV     SI,FILENAME
  2495.                CALL    CAPITALIZE
  2496. NEXT_PARSE:    CALL    PARSE_DELIMIT
  2497.                LODSB
  2498.                CMP     AL,CR
  2499.                JBE     PARSE_END1
  2500.  
  2501.                CMP     AL,"/"
  2502.                JNZ     NEXT_PARSE
  2503.                CALL    PARSE_DELIMIT
  2504.                LODSB
  2505.                CMP     AL,CR
  2506.                CLC
  2507.                JZ      PARSE_END
  2508.  
  2509. CK_SWITCH:     MOV     CX,SWITCH_LEN
  2510.                MOV     BX,CX
  2511.                MOV     DI,OFFSET SWITCH_CHARS
  2512.                MOV     DX,DI
  2513.                ADD     DX,CX
  2514.                REPNZ   SCASB
  2515.                JNZ     ILLEGAL
  2516.                SUB     BX,CX
  2517.                DEC     BX
  2518.                SHL     BX,1
  2519.                ADD     BX,DX
  2520.                CALL    [BX]                    ;Process the command.
  2521.                JC      ILLEGAL
  2522.                JMP     NEXT_PARSE
  2523.  
  2524. ILLEGAL:       MOV     DX,OFFSET ILLEGAL_PARAM
  2525.                STC
  2526.                JMP     SHORT PARSE_END
  2527.  
  2528. PARSE_END1:    CLC
  2529. PARSE_END:     RET
  2530.  
  2531. ;-----------------------------------------------------------------;
  2532. ; INPUT: SI -> string;  OUTPUT SI -> first non-white space or CR. ;
  2533. ;-----------------------------------------------------------------;
  2534. PARSE_DELIMIT: PUSH    AX
  2535. NEXT_DELIMIT:  LODSB                           ;Get a byte.
  2536.                OR      AL,AL
  2537.                JZ      LEADING_END2
  2538.                CMP     AL,CR
  2539.                JZ      LEADING_END2
  2540.                CMP     AL,SPACE                ;Is it a space char or below?
  2541.                JBE     NEXT_DELIMIT
  2542.                CMP     AL,COMMA                ;Or comma?
  2543.                JZ      NEXT_DELIMIT
  2544.                CMP     AL,";"                  ;Or semicolon?
  2545.                JZ      NEXT_DELIMIT            ;If yes, parse.
  2546. LEADING_END2:  DEC     SI                      ;Else, adjust pointer to
  2547.                POP     AX
  2548.                RET                             ; string start.
  2549.  
  2550. ;----------------------------------------------;
  2551. ; INPUT:  SI -> string;  SI preserved.         ;
  2552. ;----------------------------------------------;
  2553. CAPITALIZE:    PUSH    SI
  2554. NEXT_CAP:      LODSB
  2555.                CMP     AL,CR
  2556.                JZ      CAP_END
  2557.                OR      AL,AL
  2558.                JZ      CAP_END
  2559.                CMP     AL,"a"
  2560.                JB      NEXT_CAP
  2561.                CMP     AL,"z"
  2562.                JA      NEXT_CAP
  2563.                AND     BYTE PTR [SI - 1],5FH
  2564.                JMP     NEXT_CAP
  2565. CAP_END:       POP     SI
  2566.                RET
  2567.  
  2568. ;----------------------------------------------;
  2569. SW_PRIOR:      MOV     DATE_FLAG,PRIOR
  2570.                JMP     SHORT GET_THE_DATE
  2571.  
  2572. SW_AFTER:      MOV     DATE_FLAG,AFTER
  2573.  
  2574. GET_THE_DATE:  CALL    PARSE_DELIMIT
  2575.                CALL    GET_NUMBER              ;Get first number.
  2576.                JZ      BAD_PARAMETER           ;Was it a zero or no number?
  2577.                MOV     DH,BL                   ;If yes, exit, else store month.
  2578.                CALL    PARSE_DATE
  2579.                JC      BAD_PARAMETER
  2580.                CALL    GET_NUMBER              ;Get next number.
  2581.                JZ      BAD_PARAMETER           ;Was it zero?
  2582.                MOV     DL,BL                   ;If yes, exit, else store day.
  2583.                CALL    PARSE_DATE
  2584.                JC      BAD_PARAMETER
  2585.                CALL    GET_NUMBER              ;Get last number.
  2586.                JZ      BAD_PARAMETER           ;Was it zero?
  2587.                MOV     CX,BX                   ;If yes, exit, else store year.
  2588.                CALL    CONVERT_DATE            ;Convert decimal to compressed
  2589.                MOV     FILEDATE,DX             ; hex number and store.
  2590.                JMP     SHORT GOOD_SWITCH
  2591.  
  2592. BAD_PARAMETER: STC
  2593.                JMP     SHORT SWITCH_END
  2594.  
  2595. ;--------------;
  2596. PARSE_DATE:    LODSB
  2597.                CMP     AL,"/"
  2598.                JZ      DATE_END1
  2599.                CMP     AL,"-"
  2600.                JZ      DATE_END1
  2601.                DEC     SI
  2602.                STC
  2603.                JMP     SHORT DATE_END2
  2604.  
  2605. DATE_END1:     CLC
  2606. DATE_END2:     RET
  2607.  
  2608. ;--------------;
  2609. SW_MODIFIED:   CALL    PARSE_DELIMIT
  2610.                XOR     AL,AL
  2611.                CMP     BYTE PTR [SI],"-"
  2612.                JZ      STORE_MOD1
  2613.                MOV     AL,MODIFIED
  2614.                CMP     BYTE PTR [SI],"+"
  2615.                JNZ     STORE_MOD2
  2616. STORE_MOD1:    INC     SI
  2617. STORE_MOD2:    MOV     MODIFIED_TYPE,AL
  2618. MODIFIED_END:  JMP     SHORT GOOD_SWITCH
  2619.  
  2620. ;--------------;
  2621. SW_HIDDEN:     OR      ATTR,HIDDEN
  2622.                JMP     SHORT GOOD_SWITCH
  2623.  
  2624. ;--------------;
  2625. SW_READ_ONLY:  OR      ATTR,READ_ONLY
  2626.                JMP     SHORT GOOD_SWITCH
  2627.  
  2628. ;--------------;
  2629. SW_WORDSTAR:   MOV     WORDSTAR_MASK,7FH
  2630.                JMP     SHORT GOOD_SWITCH
  2631.  
  2632. ;--------------;
  2633. SW_NAME:       MOV     SORT_INDEX,NAME_SORT
  2634.                JMP     SHORT GOOD_SWITCH
  2635.  
  2636. ;--------------;
  2637. SW_EXT:        MOV     SORT_INDEX,EXT_SORT
  2638.                JMP     SHORT GOOD_SWITCH
  2639.  
  2640. ;--------------;
  2641. SW_SIZE:       MOV     SORT_INDEX,SIZE_SORT
  2642.                JMP     SHORT GOOD_SWITCH
  2643.  
  2644. ;--------------;
  2645. SW_DATE:       MOV     SORT_INDEX,DATE_SORT
  2646.                JMP     SHORT GOOD_SWITCH
  2647.  
  2648. ;--------------;
  2649. SW_ORIGINAL:   MOV     SORT_INDEX,NO_SORT
  2650.                JMP     SHORT GOOD_SWITCH
  2651.  
  2652. ;--------------;
  2653. SW_FORMAT:     MOV     SORT_ORDER,DESCEND
  2654. FORMAT_END:    JMP     SHORT GOOD_SWITCH
  2655.  
  2656. GOOD_SWITCH:   CLC
  2657. SWITCH_END:    RET
  2658.  
  2659. ;----------------------------------------------;
  2660. ; INPUT: SI -> ASCII number.
  2661.  
  2662. GET_NUMBER     PROC    NEAR
  2663.  
  2664.                XOR     BX,BX                   ;Start with zero.
  2665. NEXT_NUMBER:   LODSB
  2666.                MOV     CL,10
  2667.                XOR     AH,AH                   ;Zero in high half.
  2668.                CMP     AL,CR                   ;Is byte a carriage return?
  2669.                JZ      NUMBER_END              ;If yes, done.
  2670.                CMP     AL,"0"                  ;Is byte a number?
  2671.                JB      NUMBER_END
  2672.                CMP     AL,"9"
  2673.                JA      NUMBER_END              ;If no, done.
  2674.                SUB     AL,"0"                  ;Else, convert to hex.
  2675.                XCHG    AX,BX                   ;Store in BX.
  2676.                MUL     CL                      ;Multiply accumulated by 10.
  2677.                ADD     BX,AX                   ;Add new number.
  2678.                JMP     SHORT NEXT_NUMBER
  2679.  
  2680. NUMBER_END:    DEC     SI                      ;Adjust pointer to delimiter.
  2681.                OR      BX,BX                   ;Set zero flag if results zero.
  2682.                RET
  2683.  
  2684. GET_NUMBER     ENDP
  2685.  
  2686. ;---------------------------------------------------;
  2687. ; INPUT                                             ;
  2688. ;   CX = Year  (1980 - 2099)                        ;
  2689. ;   DH = Month (1 - 12)                             ;
  2690. ;   DL = Day   (1 - 31)                             ;
  2691. ;                                                   ;
  2692. ; OUTPUT                                            ;
  2693. ;   DX = compressed date in directory entry format. ;
  2694. ;                                                   ;
  2695. ;        <     DH      > <     DL      >            ;
  2696. ;        y y y y y y y m m m m d d d d d            ;
  2697. ;                                                   ;
  2698. ;              y = year  (0 - 119)                  ;
  2699. ;              m = month (1 - 12)                   ;
  2700. ;              d = day   (1 - 31)                   ;
  2701. ;                                                   ;
  2702. ;   BX, CX destroyed.                               ;
  2703. ;---------------------------------------------------;
  2704.  
  2705. CONVERT_DATE   PROC    NEAR
  2706.  
  2707.                SUB     CX,80                   ;Compress year.
  2708.                CMP     CX,1900                 ;Did user abbreviate year?
  2709.                JB      SAVE_MONTH              ;If yes, OK.
  2710.                SUB     CX,1900                 ;Else, subtract century part.
  2711. SAVE_MONTH:    MOV     BL,DH                   ;Store month in BL.
  2712.                XOR     BH,BH                   ;Zero in high half.
  2713.                SHL     CL,1                    ;Right justify year.
  2714.                MOV     DH,CL                   ;Store in DH.
  2715.                MOV     CL,5                    ;Shift month left 5 bits.
  2716.                SHL     BX,CL
  2717.                OR      DX,BX                   ;Add year and month to days.
  2718.                RET
  2719.  
  2720. CONVERT_DATE   ENDP
  2721.  
  2722. ;----------------------------------------------;
  2723. VIDEO_SETUP:   PUSH    ES
  2724.                MOV     AX,500H                 ;Make sure active page is zero.
  2725.                INT     10H
  2726.                MOV     AX,40H                  ;Point to the ROM BIOS data area
  2727.                MOV     ES,AX
  2728.                MOV     AX,ES:CRT_COLS
  2729.                MOV     COLUMNS,AX
  2730.                SHL     AX,1
  2731.                MOV     CRT_WIDTH,AX
  2732.                MOV     AX,ES:[4EH]
  2733.                MOV     CRT_START,AX
  2734.  
  2735.                MOV     AX,ES:[63H]
  2736.                ADD     AX,6
  2737.                MOV     CX,0B000H
  2738.                CMP     AX,3BAH
  2739.                JZ      STORE_SEG
  2740.                ADD     CX,800H
  2741. STORE_SEG:     MOV     STATUS_REG,AX
  2742.                MOV     VIDEO_SEG,CX
  2743.  
  2744.                MOV     SI,OFFSET MONO_ATTR
  2745.                MOV     AL,ES:CRT_MODE          ;Retrieve current video mode.
  2746.                CMP     AL,7                    ;Is it mono mode?
  2747.                JZ      GET_ROWS                ;If yes, continue.
  2748.                CMP     AL,2                    ;Is it BW80?
  2749.                JZ      GET_ROWS                ;If yes, continue.
  2750.                MOV     SI,OFFSET COLOR_ATTR
  2751.                CMP     AL,3                    ;Is it mode CO80?
  2752.                JZ      GET_ROWS                ;If yes, continue.
  2753.                MOV     AX,3                    ;Else, change video mode to CO80.
  2754.                INT     10H
  2755.  
  2756. GET_ROWS:      XOR     BH,BH
  2757.                MOV     DL,24
  2758.                MOV     AX,1130H
  2759.                INT     10H
  2760.                MOV     ROWS,DL                 ;Store rows.
  2761.                SUB     DL,3
  2762.                XOR     DH,DH
  2763.                MOV     LISTING_LEN,DX
  2764.  
  2765.                POP     ES
  2766.                MOV     DI,OFFSET COLOR
  2767.                MOV     CX,SIZE COLOR_ATTRIBS
  2768.                REP     MOVSB
  2769.  
  2770. ;----------------------------------------------;
  2771.  
  2772. DISPLAY_SETUP: CALL    CLS                     ;Clear screen.
  2773.  
  2774.                CMP     BORDER_FLAG,1
  2775.                JZ      DO_COPYRIGHT
  2776.                MOV     BL,COLOR.W              ;Turn on border.
  2777.                AND     BL,7
  2778.                XOR     BH,BH
  2779.                MOV     AH,0BH
  2780.                INT     10H
  2781.  
  2782. DO_COPYRIGHT:  XOR     AX,AX
  2783.                CALL    CALC_ADDR
  2784.                INC     DI
  2785.                INC     DI
  2786.                MOV     SI,OFFSET COPYRIGHT     ;Point to copyright message.
  2787.                MOV     BH,COLOR.B              ;Use header attribute.
  2788.                CALL    WRITE_STRING            ;And display it.
  2789.                RET
  2790.  
  2791. ;----------------------------------------------;
  2792. INIT_ZOOM:     MOV     AX,2
  2793.                CALL    CALC_ADDR
  2794.                MOV     LCOLUMN_START,DI
  2795.  
  2796.                MOV     AX,SIZE MARK + SIZE LIST_NAME + 1
  2797.                CMP     ZOOM_STATE,SHORT_NAME
  2798.                JZ      STORE_ZOOM
  2799.                MOV     AX,SIZE FILE_RECORD
  2800.                CMP     ZOOM_STATE,LONG_NAME
  2801.                JZ      STORE_ZOOM
  2802.                XOR     AX,AX
  2803.  
  2804. STORE_ZOOM:    MOV     LCOLUMN_LEN,AX
  2805.                MOV     BX,SIZE FILE_RECORD
  2806.                SUB     BX,AX
  2807.                MOV     LCOLUMN_BAL,BX
  2808.  
  2809.                OR      AX,AX
  2810.                JZ      GET_FILE_LEN
  2811.                INC     AX
  2812. GET_FILE_LEN:  MOV     BX,COLUMNS
  2813.                SUB     BX,AX
  2814.                MOV     FCOLUMN_LEN,BX
  2815.  
  2816.                SHL     AX,1
  2817.                ADD     DI,AX
  2818.                MOV     FCOLUMN_START,DI
  2819.  
  2820.                CMP     ZOOM_STATE,FULL_FILE
  2821.                JZ      INIT_ZOOM_END
  2822.                MOV     DI,FCOLUMN_START
  2823.                DEC     DI
  2824.                DEC     DI
  2825.                MOV     BH,COLOR.B
  2826.                MOV     BP,LISTING_LEN
  2827.                MOV     AL,SPACE
  2828. NEXT_DIVIDER:  PUSH    DI
  2829.                CALL    WRITE_SCREEN
  2830.                POP     DI
  2831.                ADD     DI,CRT_WIDTH
  2832.                DEC     BP
  2833.                JNZ     NEXT_DIVIDER
  2834.  
  2835. INIT_ZOOM_END: RET
  2836.  
  2837. ;----------------------------------------------;
  2838. DISPLAY_MENU:  MOV     AL,UP_ARROW
  2839.                MOV     AH,"A"
  2840.                CMP     SORT_ORDER,ASCEND
  2841.                JZ      STORE_SORT2
  2842.                MOV     AL,DOWN_ARROW
  2843.                MOV     AH,"D"
  2844.  
  2845. STORE_SORT2:   MOV     SORT_MENU1,AL
  2846.                MOV     SORT_MENU2,AH
  2847.  
  2848.                CALL    MENU_OFFSET
  2849.                PUSH    DI
  2850.                MOV     BH,COLOR.B
  2851.                MOV     SI,OFFSET MENU
  2852.                CALL    WRITE_STRING
  2853.                POP     DI
  2854.                ADD     DI,CRT_WIDTH
  2855.                CALL    WRITE_STRING
  2856.                CALL    HIDE_CURSOR
  2857. MENU_END:      RET
  2858.  
  2859. ;----------------------------------------------;
  2860. ; OUTPUT: CF=1 if Esc pressed; FILENAME -> filename.
  2861.  
  2862. ENTER_FILENAME DB      " Enter filespec: ",0
  2863. NAME_CURSOR    EQU     $ - ENTER_FILENAME
  2864. FILENAME_LEN   EQU     80 - NAME_CURSOR - 1
  2865.  
  2866. FILE_CURSOR    DW      ?
  2867.  
  2868. GET_NAME:      CALL    MENU_OFFSET
  2869.                ADD     DI,CRT_WIDTH
  2870.                MOV     BH,COLOR.B
  2871.                MOV     SI,OFFSET ENTER_FILENAME
  2872.                CALL    WRITE_STRING
  2873.  
  2874.                MOV     SI,81H
  2875.                MOV     FILE_CURSOR,SI
  2876.                MOV     DI,SI
  2877.                MOV     CX,FILENAME_LEN
  2878.                MOV     LINE_START,DI
  2879.                ADD     DI,CX
  2880.                MOV     LINE_END,DI
  2881.                MOV     DI,81H
  2882.                CALL    PARSE_DELIMIT
  2883.  
  2884. GET_END:       LODSB
  2885.                CMP     AL,"/"
  2886.                JZ      GOT_END3
  2887.                CMP     AL,SPACE
  2888.                JBE     GOT_END3
  2889.                STOSB
  2890.                JMP     GET_END
  2891.  
  2892. GOT_END3:      MOV     CX,LINE_END
  2893.                SUB     CX,DI
  2894.                INC     CX
  2895.                MOV     AL,SPACE
  2896.                REP     STOSB
  2897.                XOR     AL,AL
  2898.                STOSB
  2899.                MOV     AL,CR
  2900.                STOSB
  2901.  
  2902. NEXT_FILENAME: CALL    MENU_OFFSET
  2903.                ADD     DI,CRT_WIDTH
  2904.                ADD     DI,NAME_CURSOR * 2
  2905.                MOV     BH,COLOR.B
  2906.                MOV     SI,LINE_START
  2907.                CALL    WRITE_STRING
  2908.  
  2909.                MOV     DI,FILE_CURSOR
  2910.                MOV     DX,DI
  2911.                ADD     DL,NAME_CURSOR
  2912.                SUB     DX,LINE_START
  2913.                MOV     DH,ROWS
  2914.                CALL    SET_CURSOR
  2915.                CALL    EDITOR
  2916.                MOV     FILE_CURSOR,DI
  2917.                JC      GET_NAME_END
  2918.                CMP     AH,ENTER_SCAN
  2919.                JNZ     NEXT_FILENAME
  2920. GET_NAME_END:  RET
  2921.  
  2922. ;*************LINE EDITOR**********************;
  2923.  
  2924. LINE_START     DW      ?
  2925. LINE_END       DW      ?
  2926.  
  2927. ;INPUT: DI=buffer position; LINE_START, LINE_END.
  2928. ;OUTPUT: AL=char. AH=scan code. CY=1 if Esc pressed.
  2929.  
  2930. EDITOR:        CALL    GETKEY
  2931.                XCHG    AL,AH
  2932.                JNC     DO_EDIT
  2933.                JMP     EDITOR_END
  2934. DO_EDIT:       MOV     BX,DI
  2935.                MOV     DX,LINE_START
  2936.                MOV     CX,LINE_END
  2937.  
  2938.                CMP     AH,ENTER_SCAN
  2939.                JNZ     CK_RIGHT
  2940.                JMP     EDITOR_DONE
  2941.  
  2942. CK_RIGHT:      CMP     AX,RIGHT_SCAN SHL 8
  2943.                JNZ     CK_LEFT
  2944.                CMP     DI,CX
  2945.                JZ      EDITOR_DONE
  2946.                CMP     BYTE PTR [DI],SPACE
  2947.                JZ      EDITOR_DONE
  2948.                INC     DI
  2949.  
  2950. CK_LEFT:       CMP     AX,LEFT_SCAN SHL 8
  2951.                JNZ     CK_BS
  2952.                CMP     DI,DX
  2953.                JZ      EDITOR_DONE
  2954.                DEC     DI
  2955.  
  2956. CK_BS:         CMP     AH,BS_SCAN
  2957.                JNZ     CK_DEL
  2958.                CMP     DI,DX
  2959.                JZ      EDITOR_DONE
  2960.                DEC     DI
  2961.                CALL    CK_INSERT
  2962.                JNZ     DO_DEL
  2963.                MOV     BYTE PTR [DI],SPACE
  2964.                JMP     SHORT EDITOR_CHANGE
  2965.  
  2966. CK_DEL:        CMP     AX,DEL_SCAN SHL 8
  2967.                JNZ     CK_HOME
  2968. DO_DEL:        PUSH    DI
  2969.                MOV     SI,DI
  2970.                INC     SI
  2971.                DEC     CX
  2972.                SUB     CX,DI
  2973.                JS      DEL_END
  2974.                REP     MOVSB
  2975.                MOV     BYTE PTR [DI],SPACE
  2976. DEL_END:       POP     DI
  2977.                JMP     SHORT EDITOR_CHANGE
  2978.  
  2979. CK_HOME:       CMP     AX,HOME_SCAN SHL 8
  2980.                JNZ     CK_END2
  2981.                MOV     DI,DX
  2982.  
  2983. CK_END2:       CMP     AX,END_SCAN SHL 8
  2984.                JNZ     CK_ASCII
  2985. NEXT_CK_END2:  CMP     DI,CX
  2986.                JZ      EDITOR_DONE
  2987.                CMP     BYTE PTR [DI],SPACE
  2988.                JZ      EDITOR_DONE
  2989.                INC     DI
  2990.                JMP     NEXT_CK_END2
  2991.  
  2992. CK_ASCII:      CMP     AL,SPACE
  2993.                JB      EDITOR_DONE
  2994.                CMP     AL,127
  2995.                JA      EDITOR_DONE
  2996.                CMP     DI,LINE_END
  2997.                JAE     EDITOR_DONE
  2998.                CALL    CK_INSERT
  2999.                JNZ     DO_INSERT
  3000.                JMP     SHORT EDITOR_DONE1
  3001.  
  3002. DO_INSERT:     PUSH    DI
  3003.                DEC     CX
  3004.                MOV     DI,CX
  3005.                SUB     CX,BX
  3006.                JZ      EDITOR_DONE2
  3007.                MOV     SI,DI
  3008.                DEC     SI
  3009.                STD
  3010.                REP     MOVSB
  3011.                CLD
  3012. EDITOR_DONE2:  POP     DI
  3013. EDITOR_DONE1:  STOSB
  3014.  
  3015. EDITOR_CHANGE: ; MOV     MODIFY_FLAG,1
  3016. EDITOR_DONE:   CLC
  3017. EDITOR_END:    RET
  3018.  
  3019. ;--------------------------
  3020.  
  3021. CK_INSERT:     PUSH    DS
  3022.                MOV     DX,40H
  3023.                MOV     DS,DX
  3024.                MOV     DL,DS:[17H]
  3025.                TEST    DL,80H                  ;Insert
  3026.                POP     DS
  3027.                RET
  3028.  
  3029. ;----------------------------------------------;
  3030. ;INPUT: CX=char count; AX=character
  3031. REPEAT_CHAR:   PUSH    AX
  3032.                CALL    WRITE_SCREEN
  3033.                POP     AX
  3034.                LOOP    REPEAT_CHAR
  3035.                RET
  3036.  
  3037. ;----------------------------------------------;
  3038. ; INPUT: AX = Starting line; OUTPUT: DI = Video address.
  3039.  
  3040. CALC_ADDR:     MUL     CRT_WIDTH
  3041.                ADD     AX,CRT_START
  3042.                MOV     DI,AX
  3043.                RET
  3044.  
  3045. ;----------------------------------------------;
  3046. ; INPUT:  AL = character to write;  BH = attribute.
  3047.  
  3048. WRITE_SCREEN:  PUSH    ES
  3049.                MOV     ES,CS:VIDEO_SEG         ;Point to screen segment.
  3050.                MOV     DX,CS:STATUS_REG        ;Retrieve status register.
  3051.                MOV     BL,AL                   ;Store character in BL.
  3052.  
  3053. HORZ_RET:      IN      AL,DX                   ;Get status.
  3054.                RCR     AL,1                    ;Is it low?
  3055.                JC      HORZ_RET                ;If not, wait until it is.
  3056.                CLI                             ;No more interrupts.
  3057.  
  3058. HWAIT:         IN      AL,DX                   ;Get status.
  3059.                RCR     AL,1                    ;Is it high?
  3060.                JNC     HWAIT                   ;If no, wait until it is.
  3061.  
  3062.                MOV     AX,BX                   ;Retrieve character; now it's OK
  3063.                STOSW                           ; to write to screen buffer.
  3064.                STI                             ;Interrupts back on.
  3065.                POP     ES
  3066.                RET                             ;Return
  3067.  
  3068. ;----------------------------------------------;
  3069. ; INPUT:  ES=VIDEO_SEG; DX=STATUS_REG; AL=character to write;  BH=attribute.
  3070.  
  3071. WRITE_CHAR:    MOV     BL,AL                   ;Store character in BL.
  3072.  
  3073. HORZ_RET2:     IN      AL,DX                   ;Get status.
  3074.                RCR     AL,1                    ;Is it low?
  3075.                JC      HORZ_RET2               ;If not, wait until it is.
  3076.                CLI                             ;No more interrupts.
  3077.  
  3078. HWAIT2:        IN      AL,DX                   ;Get status.
  3079.                RCR     AL,1                    ;Is it high?
  3080.                JNC     HWAIT2                  ;If no, wait until it is.
  3081.  
  3082.                MOV     AX,BX                   ;Retrieve character; now it's OK
  3083.                STOSW                           ; to write to screen buffer.
  3084.                STI                             ;Interrupts back on.
  3085.                RET                             ;Return
  3086.  
  3087. ;----------------------------------------------;
  3088. ; INPUT:  SI -> to string to display;  DI -> where to display it.
  3089. ;   Entry point is WRITE_STRING.
  3090.  
  3091. WRITE_IT:      CALL    WRITE_SCREEN            ;Write a character.
  3092. WRITE_STRING:  LODSB                           ;Retrieve a character.
  3093.                CMP     AL,CR                   ;Keep writing until a carriage
  3094.                JA      WRITE_IT                ; return or zero encountered.
  3095.                RET
  3096.  
  3097. ;----------------------------------------------;
  3098. CLEAR_MENU:    CALL    MENU_OFFSET             ;Calculate menu screen offset.
  3099.                PUSH    DI
  3100.                MOV     BH,COLOR.B              ;Menu attribute.
  3101.                MOV     CX,CRT_WIDTH            ;Blank out the two lines of menu.
  3102. NEXT_MENU:     MOV     AL,SPACE
  3103.                CALL    WRITE_SCREEN
  3104.                LOOP    NEXT_MENU
  3105.                POP     DI
  3106.                RET
  3107.  
  3108. ;----------------------------------------;
  3109. ; OUTPUT: DI -> Screen offset for menu.  ;
  3110. ;----------------------------------------;
  3111. MENU_OFFSET:   MOV     AL,ROWS
  3112.                DEC     AL
  3113.                XOR     AH,AH
  3114.                CALL    CALC_ADDR
  3115.                RET
  3116.  
  3117. ;----------------------------------------------;
  3118. CLS:           MOV     BH,COLOR.B              ;Normal attribute.
  3119. CLS2:          XOR     CX,CX                   ;Top left corner.
  3120.                MOV     DL,BYTE PTR COLUMNS
  3121.                DEC     DL
  3122.                MOV     DH,ROWS
  3123.                MOV     AX,600H                 ;Scroll active page.
  3124.                PUSH    BP
  3125.                INT     10H
  3126.                POP     BP
  3127.                RET
  3128.  
  3129. ;----------------------------------------------;
  3130. CLOSE_SCREEN:  PUSH    AX
  3131.                MOV     BH,SCREEN_COLOR
  3132.                CALL    CLS2
  3133.  
  3134.                CMP     BORDER_FLAG,1
  3135.                JZ      PLACE_CURSOR
  3136.                XOR     BX,BX
  3137.                MOV     AH,0BH
  3138.                INT     10H
  3139.  
  3140. PLACE_CURSOR:  XOR     DX,DX
  3141.                CALL    SET_CURSOR
  3142.                POP     AX
  3143.                RET
  3144.  
  3145. ;----------------------------------------------;
  3146. BEEP:          MOV     BX,NOTE                 ;Tone frequency divisor.
  3147.                MOV     DX,12H
  3148.                XOR     AX,AX
  3149.                DIV     BX
  3150.                MOV     BX,AX                   ;8253 countdown.
  3151.  
  3152.                CALL    DELAY                   ;Wait till clock rolls over.
  3153.  
  3154.                MOV     AL,0B6H                 ;Channel 2 speaker functions.
  3155.                OUT     43H,AL                  ;8253 Mode Control.
  3156.                JMP     $+2                     ;IO delay.
  3157.                MOV     AX,BX                   ;Retrieve countdown.
  3158.                OUT     42H,AL                  ;Channel 2 LSB.
  3159.                JMP     $+2
  3160.                MOV     AL,AH                   ;Channel 2 MSB.
  3161.                OUT     42H,AL
  3162.                IN      AL,61H                  ;Port B.
  3163.                OR      AL,3                    ;Turn on speaker.
  3164.                JMP     $+2
  3165.                OUT     61H,AL
  3166.  
  3167.                CALL    DELAY                   ;Delay one second.
  3168.                IN      AL,61H                  ;Get Port B again.
  3169.                AND     AL,NOT 3                ;Turn speaker off.
  3170.                JMP     $+2
  3171.                OUT     61H,AL
  3172.                RET                             ;Done.
  3173.  
  3174. ;-----------------------------;
  3175. DELAY:         PUSH    DS                      ;Preserve data segment.
  3176.                MOV     AX,40H                  ;Point to BIOS data segment.
  3177.                MOV     DS,AX
  3178.                MOV     AX,DS:[6CH]             ;Retrieve timer low.
  3179. NEXT_BEEP:     MOV     DX,DS:[6CH]             ;Retrieve timer low.
  3180.                CMP     DX,AX                   ;Have we timed out?
  3181.                JZ      NEXT_BEEP               ;If not, wait until second up.
  3182.                POP     DS                      ;Restore data segment.
  3183.                RET
  3184.  
  3185. ;----------------------------------------------;
  3186. ; INPUT: SI-> DIR storage.
  3187.  
  3188. GET_DIR:       MOV     BYTE PTR [SI],"\"       ;DOS doesn't preface directory
  3189.                INC     SI                      ; with slash so we must.
  3190.                XOR     DL,DL
  3191.                MOV     AH,47H                  ;Get current directory.
  3192.                INT     21H
  3193.                RET
  3194.  
  3195. ;----------------------------------------------;
  3196. HIDE_CURSOR:   MOV     DH,ROWS                 ;Retrieve CRT rows.
  3197.                INC     DH                      ;Move one line below off screen.
  3198.                XOR     DL,DL                   ;Column zero.
  3199.  
  3200. SET_CURSOR:    PUSH    BX
  3201.                XOR     BH,BH                   ;Page zero.
  3202.                MOV     AH,2                    ;Set cursor position.
  3203.                INT     10H
  3204.                POP     BX
  3205.                RET
  3206.  
  3207. ;----------------------------------------------;
  3208. RESTORE_DIR:   MOV     DX,OFFSET CURRENT_DIR
  3209.  
  3210. ;----------------------------------------------;
  3211. CHANGE_DIR:    MOV     AH,3BH                  ;Change current directory.
  3212.                INT     21H
  3213.                RET
  3214.  
  3215. ;----------------------------------------------;
  3216. ; INPUT:  AL=Scan code; AH=Char; DI -> Valid scan codes table; CX = Table length
  3217. ; OUTPUT: AL=Scan code; AH=Char.
  3218.  
  3219. DISPATCH:      PUSH    AX
  3220.                MOV     BX,CX
  3221.                MOV     DX,DI
  3222.                ADD     DX,CX
  3223.                REPNZ   SCASB
  3224.                JNZ     DISPATCH_END
  3225.  
  3226. GOT_DISPATCH:  SUB     BX,CX
  3227.                DEC     BX
  3228.                SHL     BX,1
  3229.                ADD     BX,DX
  3230.                CALL    GET_PARAMS
  3231.                CALL    [BX]                    ;Process the command.
  3232. DISPATCH_END:  POP     AX
  3233.                RET
  3234.  
  3235. ;----------------------------------------------;
  3236.  
  3237. GET_PARAMS:    MOV     AX,SIZE FILE_RECORD
  3238.                MUL     LISTING_LEN
  3239.                MOV     BP,BAR_ADDR
  3240.                MOV     DX,LISTING_ADDR
  3241.                MOV     CX,LAST_ADDR
  3242. PARAMS_END:    RET
  3243.  
  3244. ;----------------------------------------------;
  3245.  
  3246. GETKEY:        TEST    KBD_STATUS,80H
  3247.                JNZ     KEY_CLEAR
  3248.                CALL    CK_KEY
  3249.                JNZ     GETKEY2
  3250.                JMP     GETKEY
  3251.  
  3252. KEY_CLEAR:     CALL    CLEAR_KEY
  3253.                MOV     KBD_STATUS,0
  3254.                CMP     FILE_CURRENT,TRUE
  3255.                JZ      GETKEY
  3256.                CALL    DISP_FILE
  3257.                JMP     GETKEY
  3258.  
  3259. GETKEY2:       XOR     AH,AH                   ;Wait for next keyboard input.
  3260.                INT     16H
  3261.                XCHG    AH,AL
  3262.                CMP     AL,ESC_SCAN
  3263.                STC
  3264.                JZ      GETKEY_END
  3265.                CLC
  3266. GETKEY_END:    RET
  3267.  
  3268. CK_KEY:        MOV     AH,1                    ;Is there a keystroke available.
  3269.                INT     16H
  3270.                RET
  3271.  
  3272. CLEAR_IT:      XOR     AH,AH
  3273.                INT     16H                     ;Read keystrokes until buffer
  3274. CLEAR_KEY:     CALL    CK_KEY                  ; empty.
  3275.                JNZ     CLEAR_IT
  3276.                RET
  3277.  
  3278. ;----------------------------------------------;
  3279.  
  3280. WRITE_TTY:     MOV     AH,0EH
  3281.                INT     10H
  3282.                RET
  3283.  
  3284. ;----------------------------------------------;
  3285. PRINT_STRING:  MOV     AH,9                    ;Print string via DOS.
  3286.                INT     21H
  3287.                RET
  3288.  
  3289. ;----------------------------------------------;
  3290. OLD9           DW      ?,?
  3291.  
  3292. INSTALL_9:     PUSH    ES
  3293.                MOV     AX,3509H                ;INT 9
  3294.                INT     21H
  3295.                MOV     OLD9[0],BX
  3296.                MOV     OLD9[2],ES
  3297.                MOV     DX,OFFSET INT_9         ;Install new interrupt.
  3298.                MOV     AX,2509H
  3299.                INT     21H
  3300.                POP     ES
  3301.                RET
  3302.  
  3303. ;----------------------------------------------;
  3304. UNINSTALL_9:   PUSH    DS
  3305.                MOV     DX,OLD9[0]              ;Restore old INT 9.
  3306.                MOV     DS,OLD9[2]
  3307.                MOV     AX,2509H
  3308.                INT     21H
  3309.                POP     DS
  3310.                RET
  3311.  
  3312. ;----------------------------------------------;
  3313. INSTALL_24:    MOV     DX,OFFSET INT_24        ;Install new interrupt.
  3314.                MOV     AX,2524H
  3315.                INT     21H
  3316.                RET
  3317.  
  3318. EVEN
  3319. STACK_POINTER  =       $ + 256
  3320.  
  3321.  
  3322. _TEXT          ENDS
  3323.                END     START
  3324.